libktx: Update to 4.3.1
This commit is contained in:
parent
16d61427ca
commit
1be2fe1f7b
|
@ -16,10 +16,12 @@ thirdparty_sources = [
|
|||
"lib/filestream.c",
|
||||
"lib/hashlist.c",
|
||||
"lib/memstream.c",
|
||||
"lib/miniz_wrapper.cpp",
|
||||
"lib/swap.c",
|
||||
"lib/texture.c",
|
||||
"lib/texture1.c",
|
||||
"lib/texture2.c",
|
||||
"lib/vkformat_check.c",
|
||||
"lib/dfdutils/createdfd.c",
|
||||
"lib/dfdutils/colourspaces.c",
|
||||
"lib/dfdutils/interpretdfd.c",
|
||||
|
@ -33,7 +35,11 @@ env_ktx.Prepend(CPPPATH=[thirdparty_dir + "include"])
|
|||
env_ktx.Prepend(CPPPATH=[thirdparty_dir + "utils"])
|
||||
env_ktx.Prepend(CPPPATH=[thirdparty_dir + "lib"])
|
||||
env_ktx.Prepend(CPPPATH=[thirdparty_dir + "other_include"])
|
||||
|
||||
env_ktx.Prepend(CPPPATH=["#thirdparty/basis_universal"])
|
||||
if env.editor_build:
|
||||
# We already build miniz in the basis_universal module (editor only).
|
||||
env_ktx.Append(CPPDEFINES=["MINIZ_HEADER_FILE_ONLY"])
|
||||
|
||||
if env["vulkan"]:
|
||||
env_ktx.Prepend(CPPPATH=["#thirdparty/vulkan/include"])
|
||||
|
|
|
@ -426,19 +426,21 @@ Files extracted from upstream source:
|
|||
## libktx
|
||||
|
||||
- Upstream: https://github.com/KhronosGroup/KTX-Software
|
||||
- Version: 4.1.0 (d7255fe73cd53b856731ceb9f2c279181d0dbbca, 2023)
|
||||
- Version: 4.3.1 (c0214158d551cfc779624b0f84130bcbbefef59a, 2024)
|
||||
- License: Apache-2.0
|
||||
|
||||
Files extracted from upstream source:
|
||||
|
||||
- `LICENSE.md`
|
||||
- `include/*`
|
||||
- `lib/dfdutils/{LICENSES/Apache-2.0.txt,KHR,*.c,*.h,*.inl}`
|
||||
- `lib/{basis_sgd.h,basis_transcode.cpp,checkheader.c,filestream.*,formatsize.h,gl_format.h,hashlist.c,ktxint.h,memstream.*,swap.c,texture*,uthash.h,vk_format.h,vkformat_enum.h}`
|
||||
- `utils/unused.h`
|
||||
- `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.*}`
|
||||
- `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,basis_transcode.cpp,miniz_wrapper.cpp,filestream.*,memstream.*,texture*}`
|
||||
- `other_include/KHR/*`
|
||||
- `utils/unused.h`
|
||||
|
||||
Some Godot-specific changes are applied via `godot.patch`.
|
||||
Some Godot-specific changes are applied via patches included in the `patches` folder.
|
||||
|
||||
|
||||
## libogg
|
||||
|
|
|
@ -1,45 +0,0 @@
|
|||
--- thirdparty/libktx/lib/gl_format.h
|
||||
+++ thirdparty/libktx/lib/gl_format.h
|
||||
@@ -92,7 +92,9 @@
|
||||
#include "vkformat_enum.h"
|
||||
|
||||
#if defined(_WIN32) && !defined(__MINGW32__)
|
||||
+#ifndef NOMINMAX
|
||||
#define NOMINMAX
|
||||
+#endif
|
||||
#ifndef __cplusplus
|
||||
#undef inline
|
||||
#define inline __inline
|
||||
--- thirdparty/libktx/lib/basis_transcode.cpp
|
||||
+++ thirdparty/libktx/lib/basis_transcode.cpp
|
||||
@@ -29,9 +29,9 @@
|
||||
#include "vkformat_enum.h"
|
||||
#include "vk_format.h"
|
||||
#include "basis_sgd.h"
|
||||
-#include "basisu/transcoder/basisu_file_headers.h"
|
||||
-#include "basisu/transcoder/basisu_transcoder.h"
|
||||
-#include "basisu/transcoder/basisu_transcoder_internal.h"
|
||||
+#include "transcoder/basisu_file_headers.h"
|
||||
+#include "transcoder/basisu_transcoder.h"
|
||||
+#include "transcoder/basisu_transcoder_internal.h"
|
||||
|
||||
#undef DECLARE_PRIVATE
|
||||
#undef DECLARE_PROTECTED
|
||||
--- thirdparty/libktx/lib/dfdutils/vk2dfd.inl
|
||||
+++ thirdparty/libktx/lib/dfdutils/vk2dfd.inl
|
||||
@@ -298,6 +298,7 @@
|
||||
case VK_FORMAT_ASTC_10x10_SFLOAT_BLOCK_EXT: return createDFDCompressed(c_ASTC, 10, 10, 1, s_SFLOAT);
|
||||
case VK_FORMAT_ASTC_12x10_SFLOAT_BLOCK_EXT: return createDFDCompressed(c_ASTC, 12, 10, 1, s_SFLOAT);
|
||||
case VK_FORMAT_ASTC_12x12_SFLOAT_BLOCK_EXT: return createDFDCompressed(c_ASTC, 12, 12, 1, s_SFLOAT);
|
||||
+#if 0
|
||||
case VK_FORMAT_ASTC_3x3x3_UNORM_BLOCK_EXT: return createDFDCompressed(c_ASTC, 3, 3, 3, s_UNORM);
|
||||
case VK_FORMAT_ASTC_3x3x3_SRGB_BLOCK_EXT: return createDFDCompressed(c_ASTC, 3, 3, 3, s_SRGB);
|
||||
case VK_FORMAT_ASTC_3x3x3_SFLOAT_BLOCK_EXT: return createDFDCompressed(c_ASTC, 3, 3, 3, s_SFLOAT);
|
||||
@@ -328,6 +329,7 @@
|
||||
case VK_FORMAT_ASTC_6x6x6_UNORM_BLOCK_EXT: return createDFDCompressed(c_ASTC, 6, 6, 6, s_UNORM);
|
||||
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_A4R4G4B4_UNORM_PACK16_EXT: {
|
||||
int channels[] = {2,1,0,3}; int bits[] = {4,4,4,4};
|
||||
return createDFDPacked(0, 4, bits, channels, s_UNORM);
|
|
@ -17,6 +17,11 @@
|
|||
#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,
|
||||
|
@ -217,41 +222,42 @@ typedef enum _khr_df_versionnumber_e {
|
|||
KHR_DF_VERSIONNUMBER_MAX = 0xFFFFU
|
||||
} khr_df_versionnumber_e;
|
||||
|
||||
/* Model in which the color coordinate space is defined.
|
||||
/** @~English
|
||||
@brief 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. */
|
||||
|
@ -260,51 +266,54 @@ 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) */
|
||||
/** BC4 - single channel interpolated 8-bit data
|
||||
(The UNORM/SNORM variation is recorded in the channel data) */
|
||||
KHR_DF_MODEL_BC4 = 131U,
|
||||
/* BC5 - two channel interpolated 8-bit data */
|
||||
/* (The UNORM/SNORM variation is recorded in the channel data) */
|
||||
/** BC5 - two channel interpolated 8-bit data
|
||||
(The UNORM/SNORM variation is recorded in the channel data) */
|
||||
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 */
|
||||
/** PowerVR Texture Compression v1 */
|
||||
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
|
||||
|
@ -520,86 +529,88 @@ typedef enum _khr_df_model_channels_e {
|
|||
KHR_DF_CHANNEL_COMMON_A = 15U
|
||||
} khr_df_model_channels_e;
|
||||
|
||||
/* Definition of the primary colors in color coordinates.
|
||||
/** @~English
|
||||
@brief 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 */
|
||||
/** 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;
|
||||
|
||||
/* Definition of the optical to digital transfer function
|
||||
/** @~English
|
||||
@brief 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. */
|
||||
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 sRGH (~2.4) */
|
||||
KHR_DF_TRANSFER_SRGB = 2U,
|
||||
/* Perceptually-linear transfer function of ITU BT.601, BT.709 and BT.2020 (~1/.45) */
|
||||
/** 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) */
|
||||
/** 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) */
|
||||
/** Perceptually-linear gamma function of original NTSC (simple 2.2 gamma) */
|
||||
KHR_DF_TRANSFER_NTSC = 4U,
|
||||
/* Sony S-log used by Sony video cameras */
|
||||
/** Sony S-log used by Sony video cameras */
|
||||
KHR_DF_TRANSFER_SLOG = 5U,
|
||||
/* Sony S-log 2 used by Sony video cameras */
|
||||
/** Sony S-log 2 used by Sony video cameras */
|
||||
KHR_DF_TRANSFER_SLOG2 = 6U,
|
||||
/* ITU BT.1886 EOTF */
|
||||
/** ITU BT.1886 EOTF */
|
||||
KHR_DF_TRANSFER_BT1886 = 7U,
|
||||
/* ITU BT.2100 HLG OETF */
|
||||
/** ITU BT.2100 HLG OETF */
|
||||
KHR_DF_TRANSFER_HLG_OETF = 8U,
|
||||
/* ITU BT.2100 HLG EOTF */
|
||||
/** ITU BT.2100 HLG EOTF */
|
||||
KHR_DF_TRANSFER_HLG_EOTF = 9U,
|
||||
/* ITU BT.2100 PQ EOTF */
|
||||
/** ITU BT.2100 PQ EOTF */
|
||||
KHR_DF_TRANSFER_PQ_EOTF = 10U,
|
||||
/* ITU BT.2100 PQ OETF */
|
||||
/** ITU BT.2100 PQ OETF */
|
||||
KHR_DF_TRANSFER_PQ_OETF = 11U,
|
||||
/* DCI P3 transfer function */
|
||||
/** DCI P3 transfer function */
|
||||
KHR_DF_TRANSFER_DCIP3 = 12U,
|
||||
/* Legacy PAL OETF */
|
||||
/** 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 */
|
||||
/** ACEScc transfer function */
|
||||
KHR_DF_TRANSFER_ACESCC = 16U,
|
||||
/* ACEScct transfer function */
|
||||
/** ACEScct transfer function */
|
||||
KHR_DF_TRANSFER_ACESCCT = 17U,
|
||||
/* Adobe RGB (1998) transfer function */
|
||||
/** Adobe RGB (1998) transfer function */
|
||||
KHR_DF_TRANSFER_ADOBERGB = 18U,
|
||||
KHR_DF_TRANSFER_MAX = 0xFFU
|
||||
} khr_df_transfer_e;
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
* @snippet{doc} version.h API version
|
||||
*/
|
||||
|
||||
#include <limits.h>
|
||||
#include <stdio.h>
|
||||
#include <stdbool.h>
|
||||
#include <sys/types.h>
|
||||
|
@ -156,6 +157,7 @@ extern "C" {
|
|||
* @brief Required unpack alignment
|
||||
*/
|
||||
#define KTX_GL_UNPACK_ALIGNMENT 4
|
||||
#define KTX_FACESLICE_WHOLE_LEVEL UINT_MAX
|
||||
|
||||
#define KTX_TRUE true
|
||||
#define KTX_FALSE false
|
||||
|
@ -176,15 +178,17 @@ typedef enum ktx_error_code_e {
|
|||
KTX_FILE_WRITE_ERROR, /*!< An error occurred while writing to the file. */
|
||||
KTX_GL_ERROR, /*!< GL operations resulted in an error. */
|
||||
KTX_INVALID_OPERATION, /*!< The operation is not allowed in the current state. */
|
||||
KTX_INVALID_VALUE, /*!< A parameter value was not valid */
|
||||
KTX_NOT_FOUND, /*!< Requested key was not found */
|
||||
KTX_INVALID_VALUE, /*!< A parameter value was not valid. */
|
||||
KTX_NOT_FOUND, /*!< Requested metadata key or required dynamically loaded GPU function was not found. */
|
||||
KTX_OUT_OF_MEMORY, /*!< Not enough memory to complete the operation. */
|
||||
KTX_TRANSCODE_FAILED, /*!< Transcoding of block compressed texture failed. */
|
||||
KTX_UNKNOWN_FILE_FORMAT, /*!< The file not a KTX file */
|
||||
KTX_UNSUPPORTED_TEXTURE_TYPE, /*!< The KTX file specifies an unsupported texture type. */
|
||||
KTX_UNSUPPORTED_FEATURE, /*!< Feature not included in in-use library or not yet implemented. */
|
||||
KTX_LIBRARY_NOT_LINKED, /*!< Library dependency (OpenGL or Vulkan) not linked into application. */
|
||||
KTX_ERROR_MAX_ENUM = KTX_LIBRARY_NOT_LINKED /*!< For safety checks. */
|
||||
KTX_DECOMPRESS_LENGTH_ERROR, /*!< Decompressed byte count does not match expected byte size */
|
||||
KTX_DECOMPRESS_CHECKSUM_ERROR, /*!< Checksum mismatch when decompressing */
|
||||
KTX_ERROR_MAX_ENUM = KTX_DECOMPRESS_CHECKSUM_ERROR /*!< For safety checks. */
|
||||
} ktx_error_code_e;
|
||||
/**
|
||||
* @deprecated
|
||||
|
@ -672,8 +676,9 @@ typedef enum ktxSupercmpScheme {
|
|||
KTX_SS_NONE = 0, /*!< No supercompression. */
|
||||
KTX_SS_BASIS_LZ = 1, /*!< Basis LZ supercompression. */
|
||||
KTX_SS_ZSTD = 2, /*!< ZStd supercompression. */
|
||||
KTX_SS_ZLIB = 3, /*!< ZLIB supercompression. */
|
||||
KTX_SS_BEGIN_RANGE = KTX_SS_NONE,
|
||||
KTX_SS_END_RANGE = KTX_SS_ZSTD,
|
||||
KTX_SS_END_RANGE = KTX_SS_ZLIB,
|
||||
KTX_SS_BEGIN_VENDOR_RANGE = 0x10000,
|
||||
KTX_SS_END_VENDOR_RANGE = 0x1ffff,
|
||||
KTX_SS_BEGIN_RESERVED = 0x20000,
|
||||
|
@ -703,15 +708,21 @@ typedef struct ktxTexture2 {
|
|||
struct ktxTexture2_private* _private; /*!< Private data. */
|
||||
} ktxTexture2;
|
||||
|
||||
/**
|
||||
* @brief Helper for casting ktxTexture1 and ktxTexture2 to ktxTexture.
|
||||
*
|
||||
* Use with caution.
|
||||
*/
|
||||
#define ktxTexture(t) ((ktxTexture*)t)
|
||||
|
||||
/**
|
||||
* @memberof ktxTexture
|
||||
* @~English
|
||||
* @brief Structure for passing texture information to ktxTexture1_Create() and
|
||||
* ktxTexture2_Create().
|
||||
* @brief Structure for passing texture information to ktxTexture1\_Create() and
|
||||
* ktxTexture2\_Create().
|
||||
*
|
||||
* @sa ktxTexture1_Create() and ktxTexture2_Create().
|
||||
* @sa @ref ktxTexture1::ktxTexture1\_Create() "ktxTexture1_Create()"
|
||||
* @sa @ref ktxTexture2::ktxTexture2\_Create() "ktxTexture2_Create()"
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
|
@ -766,9 +777,12 @@ enum ktxTextureCreateFlagBits {
|
|||
KTX_TEXTURE_CREATE_RAW_KVDATA_BIT = 0x02,
|
||||
/*!< Load the raw key-value data instead of
|
||||
creating a @c ktxHashList from it. */
|
||||
KTX_TEXTURE_CREATE_SKIP_KVDATA_BIT = 0x04
|
||||
KTX_TEXTURE_CREATE_SKIP_KVDATA_BIT = 0x04,
|
||||
/*!< Skip any key-value data. This overrides
|
||||
the RAW_KVDATA_BIT. */
|
||||
KTX_TEXTURE_CREATE_CHECK_GLTF_BASISU_BIT = 0x08
|
||||
/*!< Load texture compatible with the rules
|
||||
of KHR_texture_basisu glTF extension */
|
||||
};
|
||||
/**
|
||||
* @memberof ktxTexture
|
||||
|
@ -1053,6 +1067,9 @@ ktxTexture2_CompressBasis(ktxTexture2* This, ktx_uint32_t quality);
|
|||
KTX_API KTX_error_code KTX_APIENTRY
|
||||
ktxTexture2_DeflateZstd(ktxTexture2* This, ktx_uint32_t level);
|
||||
|
||||
KTX_API KTX_error_code KTX_APIENTRY
|
||||
ktxTexture2_DeflateZLIB(ktxTexture2* This, ktx_uint32_t level);
|
||||
|
||||
KTX_API void KTX_APIENTRY
|
||||
ktxTexture2_GetComponentInfo(ktxTexture2* This, ktx_uint32_t* numComponents,
|
||||
ktx_uint32_t* componentByteLength);
|
||||
|
@ -1682,6 +1699,19 @@ KTX_API KTX_error_code KTX_APIENTRY ktxPrintInfoForStdioStream(FILE* stdioStream
|
|||
KTX_API KTX_error_code KTX_APIENTRY ktxPrintInfoForNamedFile(const char* const filename);
|
||||
KTX_API KTX_error_code KTX_APIENTRY ktxPrintInfoForMemory(const ktx_uint8_t* bytes, ktx_size_t size);
|
||||
|
||||
/*===========================================================*
|
||||
* Utilities for printing info about a KTX2 file. *
|
||||
*===========================================================*/
|
||||
|
||||
KTX_API KTX_error_code KTX_APIENTRY ktxPrintKTX2InfoTextForMemory(const ktx_uint8_t* bytes, ktx_size_t size);
|
||||
KTX_API KTX_error_code KTX_APIENTRY ktxPrintKTX2InfoTextForNamedFile(const char* const filename);
|
||||
KTX_API KTX_error_code KTX_APIENTRY ktxPrintKTX2InfoTextForStdioStream(FILE* stdioStream);
|
||||
KTX_API KTX_error_code KTX_APIENTRY ktxPrintKTX2InfoTextForStream(ktxStream* stream);
|
||||
KTX_API KTX_error_code KTX_APIENTRY ktxPrintKTX2InfoJSONForMemory(const ktx_uint8_t* bytes, ktx_size_t size, ktx_uint32_t base_indent, ktx_uint32_t indent_width, bool minified);
|
||||
KTX_API KTX_error_code KTX_APIENTRY ktxPrintKTX2InfoJSONForNamedFile(const char* const filename, ktx_uint32_t base_indent, ktx_uint32_t indent_width, bool minified);
|
||||
KTX_API KTX_error_code KTX_APIENTRY ktxPrintKTX2InfoJSONForStdioStream(FILE* stdioStream, ktx_uint32_t base_indent, ktx_uint32_t indent_width, bool minified);
|
||||
KTX_API KTX_error_code KTX_APIENTRY ktxPrintKTX2InfoJSONForStream(ktxStream* stream, ktx_uint32_t base_indent, ktx_uint32_t indent_width, bool minified);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@ -1709,6 +1739,9 @@ KTX_API KTX_error_code KTX_APIENTRY ktxPrintInfoForMemory(const ktx_uint8_t* byt
|
|||
@~English
|
||||
@page libktx_history Revision History
|
||||
|
||||
No longer updated. Kept to preserve ancient history. For more recent history see the repo log at
|
||||
https://github.com/KhronosGroup/KTX-Software. See also the Release Notes in the repo.
|
||||
|
||||
@section v8 Version 4.0
|
||||
Added:
|
||||
@li Support for KTX Version 2.
|
||||
|
|
|
@ -23,8 +23,6 @@
|
|||
* alternative is duplicating unattractively large parts of it.
|
||||
*
|
||||
* @author Mark Callow, Edgewise Consulting
|
||||
*
|
||||
* $Date$
|
||||
*/
|
||||
|
||||
#include <ktx.h>
|
||||
|
@ -116,8 +114,9 @@ typedef struct ktxVulkanTexture
|
|||
VkImageLayout imageLayout; /*!< Layout of the created image. Has the same
|
||||
value as @p layout parameter passed to the
|
||||
loader. */
|
||||
VkDeviceMemory deviceMemory; /*!< The memory allocated for the image on
|
||||
the Vulkan device. */
|
||||
VkDeviceMemory deviceMemory; /*!< The memory (sub)allocation for the
|
||||
image on the Vulkan device. Will not be
|
||||
used with suballocators.*/
|
||||
VkImageViewType viewType; /*!< ViewType corresponding to @p image. Reflects
|
||||
the dimensionality, cubeness and arrayness
|
||||
of the image. */
|
||||
|
@ -126,15 +125,41 @@ typedef struct ktxVulkanTexture
|
|||
uint32_t depth; /*!< The depth of the image. */
|
||||
uint32_t levelCount; /*!< The number of MIP levels in the image. */
|
||||
uint32_t layerCount; /*!< The number of array layers in the image. */
|
||||
uint64_t allocationId; /*!< An id referencing suballocation(s). */
|
||||
} ktxVulkanTexture;
|
||||
|
||||
typedef uint64_t(*ktxVulkanTexture_subAllocatorAllocMemFuncPtr)(VkMemoryAllocateInfo* allocInfo, VkMemoryRequirements* memReq, uint64_t* pageCount);
|
||||
typedef VkResult(*ktxVulkanTexture_subAllocatorBindBufferFuncPtr)(VkBuffer buffer, uint64_t allocId);
|
||||
typedef VkResult(*ktxVulkanTexture_subAllocatorBindImageFuncPtr)(VkImage image, uint64_t allocId);
|
||||
typedef VkResult(*ktxVulkanTexture_subAllocatorMemoryMapFuncPtr)(uint64_t allocId, uint64_t pageNumber, VkDeviceSize *mapLength, void** dataPtr);
|
||||
typedef void (*ktxVulkanTexture_subAllocatorMemoryUnmapFuncPtr)(uint64_t allocId, uint64_t pageNumber);
|
||||
typedef void (*ktxVulkanTexture_subAllocatorFreeMemFuncPtr)(uint64_t allocId);
|
||||
/**
|
||||
* @class ktxVulkanTexture_subAllocatorCallbacks
|
||||
* @~English
|
||||
* @brief Struct that contains all callbacks necessary for suballocation.
|
||||
*
|
||||
* These pointers must all be provided for upload or destroy to occur using suballocator callbacks.
|
||||
*/
|
||||
typedef struct {
|
||||
ktxVulkanTexture_subAllocatorAllocMemFuncPtr allocMemFuncPtr; /*!< Pointer to the memory procurement function. Can suballocate one or more pages. */
|
||||
ktxVulkanTexture_subAllocatorBindBufferFuncPtr bindBufferFuncPtr; /*!< Pointer to bind-buffer-to-suballocation(s) function. */
|
||||
ktxVulkanTexture_subAllocatorBindImageFuncPtr bindImageFuncPtr; /*!< Pointer to bind-image-to-suballocation(s) function. */
|
||||
ktxVulkanTexture_subAllocatorMemoryMapFuncPtr memoryMapFuncPtr; /*!< Pointer to function for mapping the memory of a specific page. */
|
||||
ktxVulkanTexture_subAllocatorMemoryUnmapFuncPtr memoryUnmapFuncPtr; /*!< Pointer to function for unmapping the memory of a specific page. */
|
||||
ktxVulkanTexture_subAllocatorFreeMemFuncPtr freeMemFuncPtr; /*!< Pointer to the free procurement function. */
|
||||
} ktxVulkanTexture_subAllocatorCallbacks;
|
||||
|
||||
KTX_API ktx_error_code_e KTX_APIENTRY
|
||||
ktxVulkanTexture_Destruct_WithSuballocator(ktxVulkanTexture* This, VkDevice device,
|
||||
const VkAllocationCallbacks* pAllocator,
|
||||
ktxVulkanTexture_subAllocatorCallbacks* subAllocatorCallbacks);
|
||||
|
||||
KTX_API void KTX_APIENTRY
|
||||
ktxVulkanTexture_Destruct(ktxVulkanTexture* This, VkDevice device,
|
||||
const VkAllocationCallbacks* pAllocator);
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @class ktxVulkanDeviceInfo
|
||||
* @~English
|
||||
|
@ -210,6 +235,13 @@ ktxVulkanDeviceInfo_Destruct(ktxVulkanDeviceInfo* This);
|
|||
KTX_API void KTX_APIENTRY
|
||||
ktxVulkanDeviceInfo_Destroy(ktxVulkanDeviceInfo* This);
|
||||
KTX_API KTX_error_code KTX_APIENTRY
|
||||
ktxTexture_VkUploadEx_WithSuballocator(ktxTexture* This, ktxVulkanDeviceInfo* vdi,
|
||||
ktxVulkanTexture* vkTexture,
|
||||
VkImageTiling tiling,
|
||||
VkImageUsageFlags usageFlags,
|
||||
VkImageLayout finalLayout,
|
||||
ktxVulkanTexture_subAllocatorCallbacks* subAllocatorCallbacks);
|
||||
KTX_API KTX_error_code KTX_APIENTRY
|
||||
ktxTexture_VkUploadEx(ktxTexture* This, ktxVulkanDeviceInfo* vdi,
|
||||
ktxVulkanTexture* vkTexture,
|
||||
VkImageTiling tiling,
|
||||
|
@ -219,6 +251,13 @@ KTX_API KTX_error_code KTX_APIENTRY
|
|||
ktxTexture_VkUpload(ktxTexture* texture, ktxVulkanDeviceInfo* vdi,
|
||||
ktxVulkanTexture *vkTexture);
|
||||
KTX_API KTX_error_code KTX_APIENTRY
|
||||
ktxTexture1_VkUploadEx_WithSuballocator(ktxTexture1* This, ktxVulkanDeviceInfo* vdi,
|
||||
ktxVulkanTexture* vkTexture,
|
||||
VkImageTiling tiling,
|
||||
VkImageUsageFlags usageFlags,
|
||||
VkImageLayout finalLayout,
|
||||
ktxVulkanTexture_subAllocatorCallbacks* subAllocatorCallbacks);
|
||||
KTX_API KTX_error_code KTX_APIENTRY
|
||||
ktxTexture1_VkUploadEx(ktxTexture1* This, ktxVulkanDeviceInfo* vdi,
|
||||
ktxVulkanTexture* vkTexture,
|
||||
VkImageTiling tiling,
|
||||
|
@ -228,6 +267,13 @@ KTX_API KTX_error_code KTX_APIENTRY
|
|||
ktxTexture1_VkUpload(ktxTexture1* texture, ktxVulkanDeviceInfo* vdi,
|
||||
ktxVulkanTexture *vkTexture);
|
||||
KTX_API KTX_error_code KTX_APIENTRY
|
||||
ktxTexture2_VkUploadEx_WithSuballocator(ktxTexture2* This, ktxVulkanDeviceInfo* vdi,
|
||||
ktxVulkanTexture* vkTexture,
|
||||
VkImageTiling tiling,
|
||||
VkImageUsageFlags usageFlags,
|
||||
VkImageLayout finalLayout,
|
||||
ktxVulkanTexture_subAllocatorCallbacks* subAllocatorCallbacks);
|
||||
KTX_API KTX_error_code KTX_APIENTRY
|
||||
ktxTexture2_VkUploadEx(ktxTexture2* This, ktxVulkanDeviceInfo* vdi,
|
||||
ktxVulkanTexture* vkTexture,
|
||||
VkImageTiling tiling,
|
||||
|
|
|
@ -28,7 +28,7 @@ extern "C" {
|
|||
// This must be the same value as cSliceDescFlagsFrameIsIFrame so we can just
|
||||
// invert the bit when passing back & forth. As FrameIsIFrame is within
|
||||
// a C namespace it can't easily be accessed from a c header.
|
||||
enum bu_image_flags__bits_e { eBUImageIsPframe = 0x02 };
|
||||
enum bu_image_flags__bits_e { ETC1S_P_FRAME = 0x02 };
|
||||
|
||||
typedef uint32_t buFlags;
|
||||
|
||||
|
|
|
@ -372,6 +372,12 @@ ktxTexture2_transcodeUastc(ktxTexture2* This,
|
|||
This->dataSize = prototype->dataSize;
|
||||
prototype->pData = 0;
|
||||
prototype->dataSize = 0;
|
||||
// Free SGD data
|
||||
This->_private->_sgdByteLength = 0;
|
||||
if (This->_private->_supercompressionGlobalData) {
|
||||
free(This->_private->_supercompressionGlobalData);
|
||||
This->_private->_supercompressionGlobalData = NULL;
|
||||
}
|
||||
}
|
||||
ktxTexture2_Destroy(prototype);
|
||||
return result;
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/* -*- tab-width: 4; -*- */
|
||||
/* vi: set sw=2 ts=4 expandtab: */
|
||||
|
||||
/* $Id: ee6f7be4d43390de78e1815ed158012c78ddeff1 $ */
|
||||
/* $Id$ */
|
||||
|
||||
/*
|
||||
* Copyright 2010-2020 The Khronos Group Inc.
|
||||
|
@ -27,6 +27,10 @@
|
|||
|
||||
#include "ktx.h"
|
||||
#include "ktxint.h"
|
||||
#include "vkformat_enum.h"
|
||||
|
||||
bool isProhibitedFormat(VkFormat format);
|
||||
bool isValidFormat(VkFormat format);
|
||||
|
||||
/**
|
||||
* @internal
|
||||
|
@ -112,7 +116,7 @@ KTX_error_code ktxCheckHeader1_(KTX_header* pHeader,
|
|||
if (pHeader->numberOfArrayElements > 0)
|
||||
{
|
||||
/* No 3D array textures yet. */
|
||||
return KTX_UNSUPPORTED_TEXTURE_TYPE;
|
||||
return KTX_UNSUPPORTED_FEATURE;
|
||||
}
|
||||
pSuppInfo->textureDimension = 3;
|
||||
}
|
||||
|
@ -192,6 +196,20 @@ KTX_error_code ktxCheckHeader2_(KTX_header2* pHeader,
|
|||
return KTX_UNKNOWN_FILE_FORMAT;
|
||||
}
|
||||
|
||||
/* Check format */
|
||||
if (isProhibitedFormat(pHeader->vkFormat))
|
||||
{
|
||||
return KTX_FILE_DATA_ERROR;
|
||||
}
|
||||
if (!isValidFormat(pHeader->vkFormat))
|
||||
{
|
||||
return KTX_UNSUPPORTED_FEATURE;
|
||||
}
|
||||
if (pHeader->supercompressionScheme == KTX_SS_BASIS_LZ && pHeader->vkFormat != VK_FORMAT_UNDEFINED)
|
||||
{
|
||||
return KTX_FILE_DATA_ERROR;
|
||||
}
|
||||
|
||||
/* Check texture dimensions. KTX files can store 8 types of textures:
|
||||
1D, 2D, 3D, cube, and array variants of these. There is currently
|
||||
no extension for 3D array textures in any 3D API. */
|
||||
|
@ -208,7 +226,7 @@ KTX_error_code ktxCheckHeader2_(KTX_header2* pHeader,
|
|||
if (pHeader->layerCount > 0)
|
||||
{
|
||||
/* No 3D array textures yet. */
|
||||
return KTX_UNSUPPORTED_TEXTURE_TYPE;
|
||||
return KTX_UNSUPPORTED_FEATURE;
|
||||
}
|
||||
pSuppInfo->textureDimension = 3;
|
||||
}
|
||||
|
@ -228,6 +246,16 @@ KTX_error_code ktxCheckHeader2_(KTX_header2* pHeader,
|
|||
/* cube map needs 2D faces */
|
||||
return KTX_FILE_DATA_ERROR;
|
||||
}
|
||||
if (pHeader->pixelDepth != 0)
|
||||
{
|
||||
/* cube map cannot have depth */
|
||||
return KTX_FILE_DATA_ERROR;
|
||||
}
|
||||
if (pHeader->pixelWidth != pHeader->pixelHeight)
|
||||
{
|
||||
/* cube map needs square faces */
|
||||
return KTX_FILE_DATA_ERROR;
|
||||
}
|
||||
}
|
||||
else if (pHeader->faceCount != 1)
|
||||
{
|
||||
|
@ -246,6 +274,18 @@ KTX_error_code ktxCheckHeader2_(KTX_header2* pHeader,
|
|||
pSuppInfo->generateMipmaps = 0;
|
||||
}
|
||||
|
||||
// Check supercompression
|
||||
switch (pHeader->supercompressionScheme) {
|
||||
case KTX_SS_NONE:
|
||||
case KTX_SS_BASIS_LZ:
|
||||
case KTX_SS_ZSTD:
|
||||
case KTX_SS_ZLIB:
|
||||
break;
|
||||
default:
|
||||
// Unsupported supercompression
|
||||
return KTX_UNSUPPORTED_FEATURE;
|
||||
}
|
||||
|
||||
// This test works for arrays too because height or depth will be 0.
|
||||
max_dim = MAX(MAX(pHeader->pixelWidth, pHeader->pixelHeight), pHeader->pixelDepth);
|
||||
if (max_dim < ((ktx_uint32_t)1 << (pHeader->levelCount - 1)))
|
||||
|
|
|
@ -36,7 +36,7 @@ sPrimaryMapping primaryMap[] = {
|
|||
* @param[in] latitude tolerance to use while matching. A suitable value might be 0.002
|
||||
* but it depends on the application.
|
||||
*/
|
||||
khr_df_primaries_e findMapping(Primaries *p, float latitude) {
|
||||
khr_df_primaries_e findMapping(const Primaries *p, float latitude) {
|
||||
unsigned int i;
|
||||
for (i = 0; i < sizeof(primaryMap)/sizeof(sPrimaryMapping); ++i) {
|
||||
if (primaryMap[i].primaries.Rx - p->Rx <= latitude && p->Rx - primaryMap[i].primaries.Rx <= latitude &&
|
||||
|
@ -49,3 +49,23 @@ khr_df_primaries_e findMapping(Primaries *p, float latitude) {
|
|||
/* No match */
|
||||
return KHR_DF_PRIMARIES_UNSPECIFIED;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get the primaries corresponding to a KDFS primaries enum.
|
||||
*
|
||||
* @param[in] primaries the enum identifying the KDFS primaries.
|
||||
* @param[out] p pointer to a Primaries struct that will
|
||||
* be filled with the primary values.
|
||||
*/
|
||||
bool getPrimaries(khr_df_primaries_e primaries, Primaries *p) {
|
||||
unsigned int i;
|
||||
for (i = 0; i < sizeof(primaryMap)/sizeof(sPrimaryMapping); ++i) {
|
||||
if (primaryMap[i].dfPrimaryEnum == primaries) {
|
||||
*p = primaryMap[i].primaries;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/* No match */
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -15,7 +15,9 @@
|
|||
* Author: Andrew Garrard
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <KHR/khr_df.h>
|
||||
|
||||
#include "dfd.h"
|
||||
|
@ -228,6 +230,8 @@ uint32_t *createDFDUnpacked(int bigEndian, int numChannels, int bytes,
|
|||
* @param bits[] An array of length numChannels.
|
||||
* Each entry is the number of bits composing the channel, in
|
||||
* order starting at bit 0 of the packed type.
|
||||
* @param paddings[] An array of length numChannels.
|
||||
* Each entry is the number of padding bits after each channel.
|
||||
* @param channels[] An array of length numChannels.
|
||||
* Each entry enumerates the channel type: 0 = red, 1 = green,
|
||||
* 2 = blue, 15 = alpha, in order starting at bit 0 of the
|
||||
|
@ -239,9 +243,9 @@ uint32_t *createDFDUnpacked(int bigEndian, int numChannels, int bytes,
|
|||
* @return A data format descriptor in malloc'd data. The caller is responsible
|
||||
* for freeing the descriptor.
|
||||
**/
|
||||
uint32_t *createDFDPacked(int bigEndian, int numChannels,
|
||||
int bits[], int channels[],
|
||||
enum VkSuffix suffix)
|
||||
uint32_t *createDFDPackedPadded(int bigEndian, int numChannels,
|
||||
int bits[], int paddings[], int channels[],
|
||||
enum VkSuffix suffix)
|
||||
{
|
||||
uint32_t *DFD = 0;
|
||||
if (numChannels == 6) {
|
||||
|
@ -287,7 +291,7 @@ uint32_t *createDFDPacked(int bigEndian, int numChannels,
|
|||
int sampleCounter;
|
||||
for (channelCounter = 0; channelCounter < numChannels; ++channelCounter) {
|
||||
beChannelStart[channelCounter] = totalBits;
|
||||
totalBits += bits[channelCounter];
|
||||
totalBits += bits[channelCounter] + paddings[channelCounter];
|
||||
}
|
||||
BEMask = (totalBits - 1) & 0x18;
|
||||
for (channelCounter = 0; channelCounter < numChannels; ++channelCounter) {
|
||||
|
@ -297,7 +301,7 @@ uint32_t *createDFDPacked(int bigEndian, int numChannels,
|
|||
bitChannel[((bitOffset + bits[channelCounter] - 1) & ~7) ^ BEMask] = channelCounter;
|
||||
numSamples++;
|
||||
}
|
||||
bitOffset += bits[channelCounter];
|
||||
bitOffset += bits[channelCounter] + paddings[channelCounter];
|
||||
}
|
||||
DFD = writeHeader(numSamples, totalBits >> 3, suffix, i_COLOR);
|
||||
|
||||
|
@ -339,7 +343,7 @@ uint32_t *createDFDPacked(int bigEndian, int numChannels,
|
|||
int totalBits = 0;
|
||||
int bitOffset = 0;
|
||||
for (sampleCounter = 0; sampleCounter < numChannels; ++sampleCounter) {
|
||||
totalBits += bits[sampleCounter];
|
||||
totalBits += bits[sampleCounter] + paddings[sampleCounter];
|
||||
}
|
||||
|
||||
/* One sample per channel */
|
||||
|
@ -348,12 +352,98 @@ uint32_t *createDFDPacked(int bigEndian, int numChannels,
|
|||
writeSample(DFD, sampleCounter, channels[sampleCounter],
|
||||
bits[sampleCounter], bitOffset,
|
||||
1, 1, suffix);
|
||||
bitOffset += bits[sampleCounter];
|
||||
bitOffset += bits[sampleCounter] + paddings[sampleCounter];
|
||||
}
|
||||
}
|
||||
return DFD;
|
||||
}
|
||||
|
||||
/**
|
||||
* @~English
|
||||
* @brief Create a Data Format Descriptor for a packed format.
|
||||
*
|
||||
* @param bigEndian Big-endian flag: Set to 1 for big-endian byte ordering and
|
||||
* 0 for little-endian byte ordering.
|
||||
* @param numChannels The number of color channels.
|
||||
* @param bits[] An array of length numChannels.
|
||||
* Each entry is the number of bits composing the channel, in
|
||||
* order starting at bit 0 of the packed type.
|
||||
* @param channels[] An array of length numChannels.
|
||||
* Each entry enumerates the channel type: 0 = red, 1 = green,
|
||||
* 2 = blue, 15 = alpha, in order starting at bit 0 of the
|
||||
* packed type. These values match channel IDs for RGBSDA in
|
||||
* the Khronos Data Format header. To simplify iteration
|
||||
* through channels, channel id 3 is a synonym for alpha.
|
||||
* @param suffix Indicates the format suffix for the type.
|
||||
*
|
||||
* @return A data format descriptor in malloc'd data. The caller is responsible
|
||||
* for freeing the descriptor.
|
||||
**/
|
||||
uint32_t *createDFDPacked(int bigEndian, int numChannels,
|
||||
int bits[], int channels[],
|
||||
enum VkSuffix suffix) {
|
||||
assert(numChannels <= 6);
|
||||
int paddings[] = {0, 0, 0, 0, 0, 0};
|
||||
return createDFDPackedPadded(bigEndian, numChannels, bits, paddings, channels, suffix);
|
||||
}
|
||||
|
||||
uint32_t *createDFD422(int bigEndian, int numSamples,
|
||||
int bits[], int paddings[], int channels[],
|
||||
int position_xs[], int position_ys[],
|
||||
enum VkSuffix suffix) {
|
||||
assert(!bigEndian); (void) bigEndian;
|
||||
assert(suffix == s_UNORM); (void) suffix;
|
||||
|
||||
int totalBits = 0;
|
||||
for (int i = 0; i < numSamples; ++i)
|
||||
totalBits += bits[i] + paddings[i];
|
||||
assert(totalBits % 8 == 0);
|
||||
|
||||
uint32_t BDFDSize = sizeof(uint32_t) * (KHR_DF_WORD_SAMPLESTART + numSamples * KHR_DF_WORD_SAMPLEWORDS);
|
||||
uint32_t DFDSize = sizeof(uint32_t) + BDFDSize;
|
||||
uint32_t *DFD = (uint32_t *) malloc(DFDSize);
|
||||
memset(DFD, 0, DFDSize);
|
||||
DFD[0] = DFDSize;
|
||||
uint32_t *BDFD = DFD + 1;
|
||||
KHR_DFDSETVAL(BDFD, VENDORID, KHR_DF_VENDORID_KHRONOS);
|
||||
KHR_DFDSETVAL(BDFD, DESCRIPTORTYPE, KHR_DF_KHR_DESCRIPTORTYPE_BASICFORMAT);
|
||||
KHR_DFDSETVAL(BDFD, VERSIONNUMBER, KHR_DF_VERSIONNUMBER_LATEST);
|
||||
KHR_DFDSETVAL(BDFD, DESCRIPTORBLOCKSIZE, BDFDSize);
|
||||
KHR_DFDSETVAL(BDFD, MODEL, KHR_DF_MODEL_YUVSDA);
|
||||
KHR_DFDSETVAL(BDFD, PRIMARIES, KHR_DF_PRIMARIES_UNSPECIFIED);
|
||||
KHR_DFDSETVAL(BDFD, TRANSFER, KHR_DF_TRANSFER_LINEAR);
|
||||
KHR_DFDSETVAL(BDFD, FLAGS, KHR_DF_FLAG_ALPHA_STRAIGHT);
|
||||
KHR_DFDSETVAL(BDFD, TEXELBLOCKDIMENSION0, 2 - 1); // 422 contains 2 x 1 blocks
|
||||
KHR_DFDSETVAL(BDFD, TEXELBLOCKDIMENSION1, 1 - 1);
|
||||
KHR_DFDSETVAL(BDFD, TEXELBLOCKDIMENSION2, 1 - 1);
|
||||
KHR_DFDSETVAL(BDFD, TEXELBLOCKDIMENSION3, 1 - 1);
|
||||
KHR_DFDSETVAL(BDFD, BYTESPLANE0, totalBits / 8);
|
||||
KHR_DFDSETVAL(BDFD, BYTESPLANE1, 0);
|
||||
KHR_DFDSETVAL(BDFD, BYTESPLANE2, 0);
|
||||
KHR_DFDSETVAL(BDFD, BYTESPLANE3, 0);
|
||||
KHR_DFDSETVAL(BDFD, BYTESPLANE4, 0);
|
||||
KHR_DFDSETVAL(BDFD, BYTESPLANE5, 0);
|
||||
KHR_DFDSETVAL(BDFD, BYTESPLANE6, 0);
|
||||
KHR_DFDSETVAL(BDFD, BYTESPLANE7, 0);
|
||||
|
||||
int bitOffset = 0;
|
||||
for (int i = 0; i < numSamples; ++i) {
|
||||
KHR_DFDSETSVAL(BDFD, i, BITOFFSET, bitOffset);
|
||||
KHR_DFDSETSVAL(BDFD, i, BITLENGTH, bits[i] - 1);
|
||||
KHR_DFDSETSVAL(BDFD, i, CHANNELID, channels[i]);
|
||||
KHR_DFDSETSVAL(BDFD, i, QUALIFIERS, 0); // None of: FLOAT, SIGNED, EXPONENT, LINEAR
|
||||
KHR_DFDSETSVAL(BDFD, i, SAMPLEPOSITION0, position_xs[i]);
|
||||
KHR_DFDSETSVAL(BDFD, i, SAMPLEPOSITION1, position_ys[i]);
|
||||
KHR_DFDSETSVAL(BDFD, i, SAMPLEPOSITION2, 0);
|
||||
KHR_DFDSETSVAL(BDFD, i, SAMPLEPOSITION3, 0);
|
||||
KHR_DFDSETSVAL(BDFD, i, SAMPLELOWER, 0);
|
||||
KHR_DFDSETSVAL(BDFD, i, SAMPLEUPPER, (1u << bits[i]) - 1u);
|
||||
bitOffset += bits[i] + paddings[i];
|
||||
}
|
||||
|
||||
return DFD;
|
||||
}
|
||||
|
||||
static khr_df_model_e compModelMapping[] = {
|
||||
KHR_DF_MODEL_BC1A, /*!< BC1, aka DXT1, no alpha. */
|
||||
KHR_DF_MODEL_BC1A, /*!< BC1, aka DXT1, punch-through alpha. */
|
||||
|
@ -657,3 +747,39 @@ uint32_t *createDFDDepthStencil(int depthBits,
|
|||
}
|
||||
return DFD;
|
||||
}
|
||||
|
||||
/**
|
||||
* @~English
|
||||
* @brief Create a Data Format Descriptor for an alpha-only format.
|
||||
*
|
||||
* @param bigEndian Set to 1 for big-endian byte ordering and
|
||||
0 for little-endian byte ordering.
|
||||
* @param bytes The number of bytes per channel.
|
||||
* @param suffix Indicates the format suffix for the type.
|
||||
*
|
||||
* @return A data format descriptor in malloc'd data. The caller is responsible
|
||||
* for freeing the descriptor.
|
||||
**/
|
||||
uint32_t *createDFDAlpha(int bigEndian, int bytes,
|
||||
enum VkSuffix suffix) {
|
||||
uint32_t *DFD;
|
||||
int channel = 3; /* alpha channel */
|
||||
if (bigEndian) {
|
||||
int channelByte;
|
||||
/* Number of samples = number of channels * bytes per channel */
|
||||
DFD = writeHeader(bytes, bytes, suffix, i_COLOR);
|
||||
/* Loop over the bytes that constitute a channel */
|
||||
for (channelByte = 0; channelByte < bytes; ++channelByte) {
|
||||
writeSample(DFD, channelByte, channel,
|
||||
8, 8 * (bytes - channelByte - 1),
|
||||
channelByte == bytes-1, channelByte == 0, suffix);
|
||||
}
|
||||
} else { /* Little-endian */
|
||||
/* One sample per channel */
|
||||
DFD = writeHeader(1, bytes, suffix, i_COLOR);
|
||||
writeSample(DFD, 0, channel,
|
||||
8 * bytes, 0,
|
||||
1, 1, suffix);
|
||||
}
|
||||
return DFD;
|
||||
}
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
#define _DFD_H_
|
||||
|
||||
#include <KHR/khr_df.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
|
@ -72,11 +73,22 @@ uint32_t* vk2dfd(enum VkFormat format);
|
|||
uint32_t *createDFDUnpacked(int bigEndian, int numChannels, int bytes,
|
||||
int redBlueSwap, enum VkSuffix suffix);
|
||||
|
||||
/* Create a Data Format Descriptor for a packed padded format. */
|
||||
uint32_t *createDFDPackedPadded(int bigEndian, int numChannels,
|
||||
int bits[], int paddings[], int channels[],
|
||||
enum VkSuffix suffix);
|
||||
|
||||
/* Create a Data Format Descriptor for a packed format. */
|
||||
uint32_t *createDFDPacked(int bigEndian, int numChannels,
|
||||
int bits[], int channels[],
|
||||
enum VkSuffix suffix);
|
||||
|
||||
/* Create a Data Format Descriptor for a 4:2:2 format. */
|
||||
uint32_t *createDFD422(int bigEndian, int numChannels,
|
||||
int bits[], int paddings[], int channels[],
|
||||
int position_xs[], int position_ys[],
|
||||
enum VkSuffix suffix);
|
||||
|
||||
/* Create a Data Format Descriptor for a compressed format. */
|
||||
uint32_t *createDFDCompressed(enum VkCompScheme compScheme,
|
||||
int bwidth, int bheight, int bdepth,
|
||||
|
@ -87,16 +99,22 @@ uint32_t *createDFDDepthStencil(int depthBits,
|
|||
int stencilBits,
|
||||
int sizeBytes);
|
||||
|
||||
/* Create a Data Format Descriptor for an alpha-only format */
|
||||
uint32_t *createDFDAlpha(int bigEndian, int bytes,
|
||||
enum VkSuffix suffix);
|
||||
|
||||
/** @brief Result of interpreting the data format descriptor. */
|
||||
enum InterpretDFDResult {
|
||||
i_LITTLE_ENDIAN_FORMAT_BIT = 0, /*!< Confirmed little-endian (default for 8bpc). */
|
||||
i_BIG_ENDIAN_FORMAT_BIT = 1, /*!< Confirmed big-endian. */
|
||||
i_PACKED_FORMAT_BIT = 2, /*!< Packed format. */
|
||||
i_SRGB_FORMAT_BIT = 4, /*!< sRGB transfer function. */
|
||||
i_NORMALIZED_FORMAT_BIT = 8, /*!< Normalized (UNORM or SNORM). */
|
||||
i_SIGNED_FORMAT_BIT = 16, /*!< Format is signed. */
|
||||
i_FLOAT_FORMAT_BIT = 32, /*!< Format is floating point. */
|
||||
i_UNSUPPORTED_ERROR_BIT = 64, /*!< Format not successfully interpreted. */
|
||||
i_BIG_ENDIAN_FORMAT_BIT = 1u << 0u, /*!< Confirmed big-endian. */
|
||||
i_PACKED_FORMAT_BIT = 1u << 1u, /*!< Packed format. */
|
||||
i_SRGB_FORMAT_BIT = 1u << 2u, /*!< sRGB transfer function. */
|
||||
i_NORMALIZED_FORMAT_BIT = 1u << 3u, /*!< Normalized (UNORM or SNORM). */
|
||||
i_SIGNED_FORMAT_BIT = 1u << 4u, /*!< Format is signed. */
|
||||
i_FLOAT_FORMAT_BIT = 1u << 5u, /*!< Format is floating point. */
|
||||
i_COMPRESSED_FORMAT_BIT = 1u << 6u, /*!< Format is block compressed (422). */
|
||||
i_YUVSDA_FORMAT_BIT = 1u << 7u, /*!< Color model is YUVSDA. */
|
||||
i_UNSUPPORTED_ERROR_BIT = 1u << 8u, /*!< Format not successfully interpreted. */
|
||||
/** "NONTRIVIAL_ENDIANNESS" means not big-endian, not little-endian
|
||||
* (a channel has bits that are not consecutive in either order). **/
|
||||
i_UNSUPPORTED_NONTRIVIAL_ENDIANNESS = i_UNSUPPORTED_ERROR_BIT,
|
||||
|
@ -109,7 +127,9 @@ enum InterpretDFDResult {
|
|||
i_UNSUPPORTED_CHANNEL_TYPES = i_UNSUPPORTED_ERROR_BIT + 3,
|
||||
/** Only channels with the same flags are supported
|
||||
* (e.g. we don't support float red with integer green). */
|
||||
i_UNSUPPORTED_MIXED_CHANNELS = i_UNSUPPORTED_ERROR_BIT + 4
|
||||
i_UNSUPPORTED_MIXED_CHANNELS = i_UNSUPPORTED_ERROR_BIT + 4,
|
||||
/** Only 2x1 block is supported for YUVSDA model. */
|
||||
i_UNSUPPORTED_BLOCK_DIMENSIONS = i_UNSUPPORTED_ERROR_BIT + 5,
|
||||
};
|
||||
|
||||
/** @brief Interpretation of a channel from the data format descriptor. */
|
||||
|
@ -126,8 +146,47 @@ enum InterpretDFDResult interpretDFD(const uint32_t *DFD,
|
|||
InterpretedDFDChannel *A,
|
||||
uint32_t *wordBytes);
|
||||
|
||||
/* Returns the string representation.
|
||||
* If there is no direct match or the value is invalid returns NULL */
|
||||
const char* dfdToStringVendorID(khr_df_vendorid_e value);
|
||||
|
||||
/* Returns the string representation.
|
||||
* If there is no direct match or the value is invalid returns NULL */
|
||||
const char* dfdToStringDescriptorType(khr_df_khr_descriptortype_e value);
|
||||
|
||||
/* Returns the string representation.
|
||||
* If there is no direct match or the value is invalid returns NULL */
|
||||
const char* dfdToStringVersionNumber(khr_df_versionnumber_e value);
|
||||
|
||||
/* Returns the string representation of a bit in a khr_df_flags_e.
|
||||
* If there is no direct match or the value is invalid returns NULL */
|
||||
const char* dfdToStringFlagsBit(uint32_t bit_index, bool bit_value);
|
||||
|
||||
/* Returns the string representation.
|
||||
* If there is no direct match or the value is invalid returns NULL */
|
||||
const char* dfdToStringTransferFunction(khr_df_transfer_e value);
|
||||
|
||||
/* Returns the string representation.
|
||||
* If there is no direct match or the value is invalid returns NULL */
|
||||
const char* dfdToStringColorPrimaries(khr_df_primaries_e value);
|
||||
|
||||
/* Returns the string representation.
|
||||
* If there is no direct match or the value is invalid returns NULL */
|
||||
const char* dfdToStringColorModel(khr_df_model_e value);
|
||||
|
||||
/* Returns the string representation of a bit in a khr_df_sample_datatype_qualifiers_e.
|
||||
* If there is no direct match or the value is invalid returns NULL */
|
||||
const char* dfdToStringSampleDatatypeQualifiersBit(uint32_t bit_index, bool bit_value);
|
||||
|
||||
/* Returns the string representation.
|
||||
* If there is no direct match or the value is invalid returns NULL */
|
||||
const char* dfdToStringChannelId(khr_df_model_e model, khr_df_model_channels_e value);
|
||||
|
||||
/* Print a human-readable interpretation of a data format descriptor. */
|
||||
void printDFD(uint32_t *DFD);
|
||||
void printDFD(uint32_t *DFD, uint32_t dataSize);
|
||||
|
||||
/* Print a JSON interpretation of a data format descriptor. */
|
||||
void printDFDJSON(uint32_t *DFD, uint32_t dataSize, uint32_t base_indent, uint32_t indent_width, bool minified);
|
||||
|
||||
/* Get the number of components & component size from a DFD for an
|
||||
* unpacked format.
|
||||
|
@ -161,7 +220,8 @@ typedef struct _Primaries {
|
|||
float Wy; /*!< White y. */
|
||||
} Primaries;
|
||||
|
||||
khr_df_primaries_e findMapping(Primaries *p, float latitude);
|
||||
khr_df_primaries_e findMapping(const Primaries *p, float latitude);
|
||||
bool getPrimaries(khr_df_primaries_e primaries, Primaries *p);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -51,6 +51,7 @@ if (KHR_DFDVAL(dfd + 1, MODEL) == KHR_DF_MODEL_RGBSDA) {
|
|||
} else { /* Four channels, one-bit alpha */
|
||||
if (B.offset == 0) return VK_FORMAT_A1R5G5B5_UNORM_PACK16;
|
||||
if (B.offset == 1) return VK_FORMAT_R5G5B5A1_UNORM_PACK16;
|
||||
if (B.offset == 10) return VK_FORMAT_A1B5G5R5_UNORM_PACK16_KHR;
|
||||
return VK_FORMAT_B5G5R5A1_UNORM_PACK16;
|
||||
}
|
||||
} else if (wordBytes == 4) { /* PACK32 */
|
||||
|
@ -74,6 +75,9 @@ if (KHR_DFDVAL(dfd + 1, MODEL) == KHR_DF_MODEL_RGBSDA) {
|
|||
}
|
||||
} else { /* Not a packed format */
|
||||
if (wordBytes == 1) {
|
||||
if (A.size > 8 && R.size == 0 && G.size == 0 && B.size == 0 && (r & i_NORMALIZED_FORMAT_BIT) && !(r & i_SIGNED_FORMAT_BIT)) {
|
||||
return VK_FORMAT_A8_UNORM_KHR;
|
||||
}
|
||||
if (A.size > 0) { /* 4 channels */
|
||||
if (R.offset == 0) { /* RGBA */
|
||||
if ((r & i_SRGB_FORMAT_BIT)) return VK_FORMAT_R8G8B8A8_SRGB;
|
||||
|
|
|
@ -17,6 +17,14 @@
|
|||
#include <KHR/khr_df.h>
|
||||
#include "dfd.h"
|
||||
|
||||
static uint32_t bit_ceil(uint32_t x) {
|
||||
x -= 1;
|
||||
for (uint32_t i = 0; i < sizeof(x) * 8; ++i)
|
||||
if (1u << i > x)
|
||||
return 1u << i;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @~English
|
||||
* @brief Interpret a Data Format Descriptor for a simple format.
|
||||
|
@ -25,8 +33,8 @@
|
|||
described as 32-bit words in native endianness.
|
||||
Note that this is the whole descriptor, not just
|
||||
the basic descriptor block.
|
||||
* @param R Information about the decoded red channel, if any.
|
||||
* @param G Information about the decoded green channel, if any.
|
||||
* @param R Information about the decoded red channel or the depth channel, if any.
|
||||
* @param G Information about the decoded green channel or the stencil channel, if any.
|
||||
* @param B Information about the decoded blue channel, if any.
|
||||
* @param A Information about the decoded alpha channel, if any.
|
||||
* @param wordBytes Byte size of the channels (unpacked) or total size (packed).
|
||||
|
@ -54,14 +62,14 @@ enum InterpretDFDResult interpretDFD(const uint32_t *DFD,
|
|||
const uint32_t *BDFDB = DFD+1;
|
||||
|
||||
uint32_t numSamples = KHR_DFDSAMPLECOUNT(BDFDB);
|
||||
if (numSamples == 0)
|
||||
return i_UNSUPPORTED_CHANNEL_TYPES;
|
||||
|
||||
uint32_t sampleCounter;
|
||||
int determinedEndianness = 0;
|
||||
int determinedNormalizedness = 0;
|
||||
int determinedSignedness = 0;
|
||||
int determinedFloatness = 0;
|
||||
enum InterpretDFDResult result = 0; /* Build this up incrementally. */
|
||||
|
||||
bool isDepthStencil = false;
|
||||
|
||||
/* Clear these so following code doesn't get confused. */
|
||||
R->offset = R->size = 0;
|
||||
G->offset = G->size = 0;
|
||||
|
@ -76,270 +84,322 @@ enum InterpretDFDResult interpretDFD(const uint32_t *DFD,
|
|||
if ((BDFDB[KHR_DF_WORD_BYTESPLANE0] & ~KHR_DF_MASK_BYTESPLANE0)
|
||||
|| BDFDB[KHR_DF_WORD_BYTESPLANE4]) return i_UNSUPPORTED_MULTIPLE_PLANES;
|
||||
|
||||
/* Only support the RGB color model. */
|
||||
/* We could expand this to allow "UNSPECIFIED" as well. */
|
||||
if (KHR_DFDVAL(BDFDB, MODEL) != KHR_DF_MODEL_RGBSDA) return i_UNSUPPORTED_CHANNEL_TYPES;
|
||||
|
||||
/* We only pay attention to sRGB. */
|
||||
if (KHR_DFDVAL(BDFDB, TRANSFER) == KHR_DF_TRANSFER_SRGB) result |= i_SRGB_FORMAT_BIT;
|
||||
|
||||
/* We only support samples at coordinate 0,0,0,0. */
|
||||
/* (We could confirm this from texel_block_dimensions in 1.2, but */
|
||||
/* the interpretation might change in later versions.) */
|
||||
for (sampleCounter = 0; sampleCounter < numSamples; ++sampleCounter) {
|
||||
if (KHR_DFDSVAL(BDFDB, sampleCounter, SAMPLEPOSITION_ALL))
|
||||
return i_UNSUPPORTED_MULTIPLE_SAMPLE_LOCATIONS;
|
||||
}
|
||||
|
||||
/* Set flags and check for consistency. */
|
||||
for (sampleCounter = 0; sampleCounter < numSamples; ++sampleCounter) {
|
||||
/* Note: We're ignoring 9995, which is weird and worth special-casing */
|
||||
/* rather than trying to generalise to all float formats. */
|
||||
if (!determinedFloatness) {
|
||||
if (KHR_DFDSVAL(BDFDB, sampleCounter, QUALIFIERS)
|
||||
& KHR_DF_SAMPLE_DATATYPE_FLOAT) {
|
||||
result |= i_FLOAT_FORMAT_BIT;
|
||||
determinedFloatness = 1;
|
||||
}
|
||||
} else {
|
||||
/* Check whether we disagree with our predetermined floatness. */
|
||||
/* Note that this could justifiably happen with (say) D24S8. */
|
||||
if (KHR_DFDSVAL(BDFDB, sampleCounter, QUALIFIERS)
|
||||
& KHR_DF_SAMPLE_DATATYPE_FLOAT) {
|
||||
if (!(result & i_FLOAT_FORMAT_BIT)) return i_UNSUPPORTED_MIXED_CHANNELS;
|
||||
} else {
|
||||
if ((result & i_FLOAT_FORMAT_BIT)) return i_UNSUPPORTED_MIXED_CHANNELS;
|
||||
}
|
||||
}
|
||||
if (!determinedSignedness) {
|
||||
if (KHR_DFDSVAL(BDFDB, sampleCounter, QUALIFIERS)
|
||||
& KHR_DF_SAMPLE_DATATYPE_SIGNED) {
|
||||
result |= i_SIGNED_FORMAT_BIT;
|
||||
determinedSignedness = 1;
|
||||
}
|
||||
} else {
|
||||
/* Check whether we disagree with our predetermined signedness. */
|
||||
if (KHR_DFDSVAL(BDFDB, sampleCounter, QUALIFIERS)
|
||||
& KHR_DF_SAMPLE_DATATYPE_SIGNED) {
|
||||
if (!(result & i_SIGNED_FORMAT_BIT)) return i_UNSUPPORTED_MIXED_CHANNELS;
|
||||
} else {
|
||||
if ((result & i_SIGNED_FORMAT_BIT)) return i_UNSUPPORTED_MIXED_CHANNELS;
|
||||
}
|
||||
}
|
||||
/* We define "unnormalized" as "sample_upper = 1". */
|
||||
/* We don't check whether any non-1 normalization value is correct */
|
||||
/* (i.e. set to the maximum bit value, and check min value) on */
|
||||
/* the assumption that we're looking at a format which *came* from */
|
||||
/* an API we can support. */
|
||||
if (!determinedNormalizedness) {
|
||||
/* The ambiguity here is if the bottom bit is a single-bit value, */
|
||||
/* as in RGBA 5:5:5:1, so we defer the decision if the channel only has one bit. */
|
||||
if (KHR_DFDSVAL(BDFDB, sampleCounter, BITLENGTH) > 0) {
|
||||
if ((result & i_FLOAT_FORMAT_BIT)) {
|
||||
if (*(float *)(void *)&BDFDB[KHR_DF_WORD_SAMPLESTART +
|
||||
KHR_DF_WORD_SAMPLEWORDS * sampleCounter +
|
||||
KHR_DF_SAMPLEWORD_SAMPLEUPPER] != 1.0f) {
|
||||
result |= i_NORMALIZED_FORMAT_BIT;
|
||||
}
|
||||
} else {
|
||||
if (KHR_DFDSVAL(BDFDB, sampleCounter, SAMPLEUPPER) != 1U) {
|
||||
result |= i_NORMALIZED_FORMAT_BIT;
|
||||
}
|
||||
}
|
||||
determinedNormalizedness = 1;
|
||||
}
|
||||
}
|
||||
/* Note: We don't check for inconsistent normalization, because */
|
||||
/* channels composed of multiple samples will have 0 in the */
|
||||
/* lower/upper range. */
|
||||
/* This heuristic should handle 64-bit integers, too. */
|
||||
}
|
||||
|
||||
/* If this is a packed format, we work out our offsets differently. */
|
||||
/* We assume a packed format has channels that aren't byte-aligned. */
|
||||
/* If we have a format in which every channel is byte-aligned *and* packed, */
|
||||
/* we have the RGBA/ABGR ambiguity; we *probably* don't want the packed */
|
||||
/* version in this case, and if hardware has to pack it and swizzle, */
|
||||
/* that's up to the hardware to special-case. */
|
||||
for (sampleCounter = 0; sampleCounter < numSamples; ++sampleCounter) {
|
||||
if (KHR_DFDSVAL(BDFDB, sampleCounter, BITOFFSET) & 0x7U) {
|
||||
for (uint32_t sampleCounter = 0; sampleCounter < numSamples; ++sampleCounter) {
|
||||
uint32_t offset = KHR_DFDSVAL(BDFDB, sampleCounter, BITOFFSET);
|
||||
uint32_t length = KHR_DFDSVAL(BDFDB, sampleCounter, BITLENGTH) + 1;
|
||||
if ((offset & 0x7U) || ((offset + length) & 0x7U)) {
|
||||
result |= i_PACKED_FORMAT_BIT;
|
||||
/* Once we're packed, we're packed, no need to keep checking. */
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Remember: the canonical ordering of samples is to start with */
|
||||
/* the lowest bit of the channel/location which touches bit 0 of */
|
||||
/* the data, when the latter is concatenated in little-endian order, */
|
||||
/* and then progress until all the bits of that channel/location */
|
||||
/* have been processed. Multiple channels sharing the same source */
|
||||
/* bits are processed in channel ID order. (I should clarify this */
|
||||
/* for partially-shared data, but it doesn't really matter so long */
|
||||
/* as everything is consecutive, except to make things canonical.) */
|
||||
/* Note: For standard formats we could determine big/little-endianness */
|
||||
/* simply from whether the first sample starts in bit 0; technically */
|
||||
/* it's possible to have a format with unaligned channels wherein the */
|
||||
/* first channel starts at bit 0 and is one byte, yet other channels */
|
||||
/* take more bytes or aren't aligned (e.g. D24S8), but this should be */
|
||||
/* irrelevant for the formats that we support. */
|
||||
if ((result & i_PACKED_FORMAT_BIT)) {
|
||||
/* A packed format. */
|
||||
uint32_t currentChannel = ~0U; /* Don't start matched. */
|
||||
uint32_t currentBitOffset = 0;
|
||||
uint32_t currentByteOffset = 0;
|
||||
uint32_t currentBitLength = 0;
|
||||
*wordBytes = (BDFDB[KHR_DF_WORD_BYTESPLANE0] & 0xFFU);
|
||||
for (sampleCounter = 0; sampleCounter < numSamples; ++sampleCounter) {
|
||||
uint32_t sampleBitOffset = KHR_DFDSVAL(BDFDB, sampleCounter, BITOFFSET);
|
||||
uint32_t sampleByteOffset = sampleBitOffset >> 3U;
|
||||
/* The sample bitLength field stores the bit length - 1. */
|
||||
uint32_t sampleBitLength = KHR_DFDSVAL(BDFDB, sampleCounter, BITLENGTH) + 1;
|
||||
uint32_t sampleChannel = KHR_DFDSVAL(BDFDB, sampleCounter, CHANNELID);
|
||||
InterpretedDFDChannel *sampleChannelPtr;
|
||||
switch (sampleChannel) {
|
||||
case KHR_DF_CHANNEL_RGBSDA_RED:
|
||||
sampleChannelPtr = R;
|
||||
// Check data types.
|
||||
bool hasSigned = false;
|
||||
bool hasFloat = false;
|
||||
bool hasNormalized = false;
|
||||
|
||||
// Note: We're ignoring 9995, which is weird and worth special-casing
|
||||
// rather than trying to generalise to all float formats.
|
||||
for (uint32_t i = 0; i < numSamples; ++i) {
|
||||
const bool isSigned = (KHR_DFDSVAL(BDFDB, i, QUALIFIERS) & KHR_DF_SAMPLE_DATATYPE_SIGNED) != 0;
|
||||
const bool isFloat = (KHR_DFDSVAL(BDFDB, i, QUALIFIERS) & KHR_DF_SAMPLE_DATATYPE_FLOAT) != 0;
|
||||
|
||||
// We define "unnormalized" as "sample_upper = 1" or "sample_upper = 1.0f".
|
||||
// We don't check whether any non-1 normalization value is correct
|
||||
// (i.e. set to the maximum bit value, and check min value) on
|
||||
// the assumption that we're looking at a format which *came* from
|
||||
// an API we can support.
|
||||
const bool isNormalized = isFloat ?
|
||||
*(float*) (void*) &BDFDB[KHR_DF_WORD_SAMPLESTART +
|
||||
KHR_DF_WORD_SAMPLEWORDS * i +
|
||||
KHR_DF_SAMPLEWORD_SAMPLEUPPER] != 1.0f :
|
||||
KHR_DFDSVAL(BDFDB, i, SAMPLEUPPER) != 1U;
|
||||
|
||||
hasSigned |= isSigned;
|
||||
hasFloat |= isFloat;
|
||||
// By our definition the normalizedness of a single bit channel (like in RGBA 5:5:5:1)
|
||||
// is ambiguous. Ignore these during normalized checks.
|
||||
if (KHR_DFDSVAL(BDFDB, i, BITLENGTH) > 0)
|
||||
hasNormalized |= isNormalized;
|
||||
}
|
||||
result |= hasSigned ? i_SIGNED_FORMAT_BIT : 0;
|
||||
result |= hasFloat ? i_FLOAT_FORMAT_BIT : 0;
|
||||
result |= hasNormalized ? i_NORMALIZED_FORMAT_BIT : 0;
|
||||
|
||||
// Checks based on color model
|
||||
if (KHR_DFDVAL(BDFDB, MODEL) == KHR_DF_MODEL_YUVSDA) {
|
||||
result |= i_NORMALIZED_FORMAT_BIT;
|
||||
result |= i_COMPRESSED_FORMAT_BIT;
|
||||
result |= i_YUVSDA_FORMAT_BIT;
|
||||
|
||||
for (uint32_t i = 0; i < numSamples; ++i) {
|
||||
switch (KHR_DFDSVAL(BDFDB, i, CHANNELID)) {
|
||||
case KHR_DF_CHANNEL_YUVSDA_Y:
|
||||
case KHR_DF_CHANNEL_YUVSDA_U:
|
||||
case KHR_DF_CHANNEL_YUVSDA_V:
|
||||
case KHR_DF_CHANNEL_YUVSDA_A:
|
||||
break;
|
||||
case KHR_DF_CHANNEL_RGBSDA_GREEN:
|
||||
sampleChannelPtr = G;
|
||||
break;
|
||||
case KHR_DF_CHANNEL_RGBSDA_BLUE:
|
||||
sampleChannelPtr = B;
|
||||
break;
|
||||
case KHR_DF_CHANNEL_RGBSDA_ALPHA:
|
||||
sampleChannelPtr = A;
|
||||
case KHR_DF_CHANNEL_YUVSDA_DEPTH:
|
||||
case KHR_DF_CHANNEL_YUVSDA_STENCIL:
|
||||
isDepthStencil = true;
|
||||
break;
|
||||
default:
|
||||
return i_UNSUPPORTED_CHANNEL_TYPES;
|
||||
}
|
||||
if (sampleChannel == currentChannel) {
|
||||
/* Continuation of the same channel. */
|
||||
/* Since a big (>32-bit) channel isn't "packed", */
|
||||
/* this should only happen in big-endian, or if */
|
||||
/* we have a wacky format that we won't support. */
|
||||
if (sampleByteOffset == currentByteOffset - 1U && /* One byte earlier */
|
||||
((currentBitOffset + currentBitLength) & 7U) == 0 && /* Already at the end of a byte */
|
||||
(sampleBitOffset & 7U) == 0) { /* Start at the beginning of the byte */
|
||||
/* All is good, continue big-endian. */
|
||||
/* N.B. We shouldn't be here if we decided we were little-endian, */
|
||||
/* so we don't bother to check that disagreement. */
|
||||
result |= i_BIG_ENDIAN_FORMAT_BIT;
|
||||
determinedEndianness = 1;
|
||||
} else {
|
||||
/* Oh dear. */
|
||||
/* We could be little-endian, but not with any standard format. */
|
||||
/* More likely we've got something weird that we can't support. */
|
||||
return i_UNSUPPORTED_NONTRIVIAL_ENDIANNESS;
|
||||
}
|
||||
/* Remember where we are. */
|
||||
currentBitOffset = sampleBitOffset;
|
||||
currentByteOffset = sampleByteOffset;
|
||||
currentBitLength = sampleBitLength;
|
||||
/* Accumulate the bit length. */
|
||||
sampleChannelPtr->size += sampleBitLength;
|
||||
} else {
|
||||
/* Everything is new. Hopefully. */
|
||||
currentChannel = sampleChannel;
|
||||
currentBitOffset = sampleBitOffset;
|
||||
currentByteOffset = sampleByteOffset;
|
||||
currentBitLength = sampleBitLength;
|
||||
if (sampleChannelPtr->size) {
|
||||
/* Uh-oh, we've seen this channel before. */
|
||||
return i_UNSUPPORTED_NONTRIVIAL_ENDIANNESS;
|
||||
}
|
||||
/* For now, record the bit offset in little-endian terms, */
|
||||
/* because we may not know to reverse it yet. */
|
||||
sampleChannelPtr->offset = sampleBitOffset;
|
||||
sampleChannelPtr->size = sampleBitLength;
|
||||
}
|
||||
|
||||
// Determine wordBytes
|
||||
uint32_t largestSampleSize = 0;
|
||||
for (uint32_t i = 0; i < numSamples; ++i) {
|
||||
uint32_t length = KHR_DFDSVAL(BDFDB, i, BITLENGTH) + 1;
|
||||
if (largestSampleSize < length)
|
||||
largestSampleSize = length;
|
||||
}
|
||||
*wordBytes = ((result & i_PACKED_FORMAT_BIT) ? 4 : 1) * bit_ceil(largestSampleSize) / 8;
|
||||
|
||||
} else if (KHR_DFDVAL(BDFDB, MODEL) == KHR_DF_MODEL_RGBSDA) {
|
||||
/* We only pay attention to sRGB. */
|
||||
if (KHR_DFDVAL(BDFDB, TRANSFER) == KHR_DF_TRANSFER_SRGB) result |= i_SRGB_FORMAT_BIT;
|
||||
|
||||
/* We only support samples at coordinate 0,0,0,0. */
|
||||
/* (We could confirm this from texel_block_dimensions in 1.2, but */
|
||||
/* the interpretation might change in later versions.) */
|
||||
for (uint32_t sampleCounter = 0; sampleCounter < numSamples; ++sampleCounter) {
|
||||
if (KHR_DFDSVAL(BDFDB, sampleCounter, SAMPLEPOSITION_ALL))
|
||||
return i_UNSUPPORTED_MULTIPLE_SAMPLE_LOCATIONS;
|
||||
}
|
||||
|
||||
/* For Depth/Stencil formats mixed channels are allowed */
|
||||
for (uint32_t sampleCounter = 0; sampleCounter < numSamples; ++sampleCounter) {
|
||||
switch (KHR_DFDSVAL(BDFDB, sampleCounter, CHANNELID)) {
|
||||
case KHR_DF_CHANNEL_RGBSDA_DEPTH:
|
||||
case KHR_DF_CHANNEL_RGBSDA_STENCIL:
|
||||
isDepthStencil = true;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ((result & i_BIG_ENDIAN_FORMAT_BIT)) {
|
||||
/* Our bit offsets to bit 0 of each channel are in little-endian terms. */
|
||||
/* We need to do a byte swap to work out where they should be. */
|
||||
/* We assume, for sanity, that byte sizes are a power of two for this. */
|
||||
uint32_t offsetMask = (*wordBytes - 1U) << 3U;
|
||||
R->offset ^= offsetMask;
|
||||
G->offset ^= offsetMask;
|
||||
B->offset ^= offsetMask;
|
||||
A->offset ^= offsetMask;
|
||||
|
||||
// Check for mixed channels
|
||||
if (!isDepthStencil) {
|
||||
for (uint32_t i = 0; i < numSamples; ++i) {
|
||||
const bool isSigned = (KHR_DFDSVAL(BDFDB, i, QUALIFIERS) & KHR_DF_SAMPLE_DATATYPE_SIGNED) != 0;
|
||||
const bool isFloat = (KHR_DFDSVAL(BDFDB, i, QUALIFIERS) & KHR_DF_SAMPLE_DATATYPE_FLOAT) != 0;
|
||||
|
||||
if (isSigned != hasSigned)
|
||||
return i_UNSUPPORTED_MIXED_CHANNELS;
|
||||
if (isFloat != hasFloat)
|
||||
return i_UNSUPPORTED_MIXED_CHANNELS;
|
||||
|
||||
// Note: We don't check for inconsistent normalization, because
|
||||
// channels composed of multiple samples will have 0 in the
|
||||
// lower/upper range. Single bit channels are also ambiguous.
|
||||
// This heuristic should handle 64-bit integers, too.
|
||||
}
|
||||
}
|
||||
|
||||
/* Remember: the canonical ordering of samples is to start with */
|
||||
/* the lowest bit of the channel/location which touches bit 0 of */
|
||||
/* the data, when the latter is concatenated in little-endian order, */
|
||||
/* and then progress until all the bits of that channel/location */
|
||||
/* have been processed. Multiple channels sharing the same source */
|
||||
/* bits are processed in channel ID order. (I should clarify this */
|
||||
/* for partially-shared data, but it doesn't really matter so long */
|
||||
/* as everything is consecutive, except to make things canonical.) */
|
||||
/* Note: For standard formats we could determine big/little-endianness */
|
||||
/* simply from whether the first sample starts in bit 0; technically */
|
||||
/* it's possible to have a format with unaligned channels wherein the */
|
||||
/* first channel starts at bit 0 and is one byte, yet other channels */
|
||||
/* take more bytes or aren't aligned (e.g. D24S8), but this should be */
|
||||
/* irrelevant for the formats that we support. */
|
||||
if ((result & i_PACKED_FORMAT_BIT)) {
|
||||
/* A packed format. */
|
||||
uint32_t currentChannel = ~0U; /* Don't start matched. */
|
||||
uint32_t currentBitOffset = 0;
|
||||
uint32_t currentByteOffset = 0;
|
||||
uint32_t currentBitLength = 0;
|
||||
*wordBytes = (BDFDB[KHR_DF_WORD_BYTESPLANE0] & 0xFFU);
|
||||
for (uint32_t sampleCounter = 0; sampleCounter < numSamples; ++sampleCounter) {
|
||||
uint32_t sampleBitOffset = KHR_DFDSVAL(BDFDB, sampleCounter, BITOFFSET);
|
||||
uint32_t sampleByteOffset = sampleBitOffset >> 3U;
|
||||
/* The sample bitLength field stores the bit length - 1. */
|
||||
uint32_t sampleBitLength = KHR_DFDSVAL(BDFDB, sampleCounter, BITLENGTH) + 1;
|
||||
uint32_t sampleChannel = KHR_DFDSVAL(BDFDB, sampleCounter, CHANNELID);
|
||||
InterpretedDFDChannel *sampleChannelPtr;
|
||||
switch (sampleChannel) {
|
||||
case KHR_DF_CHANNEL_RGBSDA_RED:
|
||||
sampleChannelPtr = R;
|
||||
break;
|
||||
case KHR_DF_CHANNEL_RGBSDA_GREEN:
|
||||
sampleChannelPtr = G;
|
||||
break;
|
||||
case KHR_DF_CHANNEL_RGBSDA_BLUE:
|
||||
sampleChannelPtr = B;
|
||||
break;
|
||||
case KHR_DF_CHANNEL_RGBSDA_DEPTH:
|
||||
sampleChannelPtr = R;
|
||||
break;
|
||||
case KHR_DF_CHANNEL_RGBSDA_STENCIL:
|
||||
sampleChannelPtr = G;
|
||||
break;
|
||||
case KHR_DF_CHANNEL_RGBSDA_ALPHA:
|
||||
sampleChannelPtr = A;
|
||||
break;
|
||||
default:
|
||||
return i_UNSUPPORTED_CHANNEL_TYPES;
|
||||
}
|
||||
if (sampleChannel == currentChannel) {
|
||||
/* Continuation of the same channel. */
|
||||
/* Since a big (>32-bit) channel isn't "packed", */
|
||||
/* this should only happen in big-endian, or if */
|
||||
/* we have a wacky format that we won't support. */
|
||||
if (sampleByteOffset == currentByteOffset - 1U && /* One byte earlier */
|
||||
((currentBitOffset + currentBitLength) & 7U) == 0 && /* Already at the end of a byte */
|
||||
(sampleBitOffset & 7U) == 0) { /* Start at the beginning of the byte */
|
||||
/* All is good, continue big-endian. */
|
||||
/* N.B. We shouldn't be here if we decided we were little-endian, */
|
||||
/* so we don't bother to check that disagreement. */
|
||||
result |= i_BIG_ENDIAN_FORMAT_BIT;
|
||||
determinedEndianness = 1;
|
||||
} else {
|
||||
/* Oh dear. */
|
||||
/* We could be little-endian, but not with any standard format. */
|
||||
/* More likely we've got something weird that we can't support. */
|
||||
return i_UNSUPPORTED_NONTRIVIAL_ENDIANNESS;
|
||||
}
|
||||
/* Remember where we are. */
|
||||
currentBitOffset = sampleBitOffset;
|
||||
currentByteOffset = sampleByteOffset;
|
||||
currentBitLength = sampleBitLength;
|
||||
/* Accumulate the bit length. */
|
||||
sampleChannelPtr->size += sampleBitLength;
|
||||
} else {
|
||||
/* Everything is new. Hopefully. */
|
||||
currentChannel = sampleChannel;
|
||||
currentBitOffset = sampleBitOffset;
|
||||
currentByteOffset = sampleByteOffset;
|
||||
currentBitLength = sampleBitLength;
|
||||
if (sampleChannelPtr->size) {
|
||||
/* Uh-oh, we've seen this channel before. */
|
||||
return i_UNSUPPORTED_NONTRIVIAL_ENDIANNESS;
|
||||
}
|
||||
/* For now, record the bit offset in little-endian terms, */
|
||||
/* because we may not know to reverse it yet. */
|
||||
sampleChannelPtr->offset = sampleBitOffset;
|
||||
sampleChannelPtr->size = sampleBitLength;
|
||||
}
|
||||
}
|
||||
if ((result & i_BIG_ENDIAN_FORMAT_BIT)) {
|
||||
/* Our bit offsets to bit 0 of each channel are in little-endian terms. */
|
||||
/* We need to do a byte swap to work out where they should be. */
|
||||
/* We assume, for sanity, that byte sizes are a power of two for this. */
|
||||
uint32_t offsetMask = (*wordBytes - 1U) << 3U;
|
||||
R->offset ^= offsetMask;
|
||||
G->offset ^= offsetMask;
|
||||
B->offset ^= offsetMask;
|
||||
A->offset ^= offsetMask;
|
||||
}
|
||||
} else {
|
||||
/* Not a packed format. */
|
||||
/* Everything is byte-aligned. */
|
||||
/* Question is whether there multiple samples per channel. */
|
||||
uint32_t currentChannel = ~0U; /* Don't start matched. */
|
||||
uint32_t currentByteOffset = 0;
|
||||
uint32_t currentByteLength = 0;
|
||||
for (uint32_t sampleCounter = 0; sampleCounter < numSamples; ++sampleCounter) {
|
||||
uint32_t sampleByteOffset = KHR_DFDSVAL(BDFDB, sampleCounter, BITOFFSET) >> 3U;
|
||||
uint32_t sampleByteLength = (KHR_DFDSVAL(BDFDB, sampleCounter, BITLENGTH) + 1) >> 3U;
|
||||
uint32_t sampleChannel = KHR_DFDSVAL(BDFDB, sampleCounter, CHANNELID);
|
||||
InterpretedDFDChannel *sampleChannelPtr;
|
||||
switch (sampleChannel) {
|
||||
case KHR_DF_CHANNEL_RGBSDA_RED:
|
||||
sampleChannelPtr = R;
|
||||
break;
|
||||
case KHR_DF_CHANNEL_RGBSDA_GREEN:
|
||||
sampleChannelPtr = G;
|
||||
break;
|
||||
case KHR_DF_CHANNEL_RGBSDA_BLUE:
|
||||
sampleChannelPtr = B;
|
||||
break;
|
||||
case KHR_DF_CHANNEL_RGBSDA_DEPTH:
|
||||
sampleChannelPtr = R;
|
||||
break;
|
||||
case KHR_DF_CHANNEL_RGBSDA_STENCIL:
|
||||
sampleChannelPtr = G;
|
||||
break;
|
||||
case KHR_DF_CHANNEL_RGBSDA_ALPHA:
|
||||
sampleChannelPtr = A;
|
||||
break;
|
||||
default:
|
||||
return i_UNSUPPORTED_CHANNEL_TYPES;
|
||||
}
|
||||
if (sampleChannel == currentChannel) {
|
||||
/* Continuation of the same channel. */
|
||||
/* Either big-endian, or little-endian with a very large channel. */
|
||||
if (sampleByteOffset == currentByteOffset - 1) { /* One byte earlier */
|
||||
if (determinedEndianness && !(result & i_BIG_ENDIAN_FORMAT_BIT)) {
|
||||
return i_UNSUPPORTED_NONTRIVIAL_ENDIANNESS;
|
||||
}
|
||||
/* All is good, continue big-endian. */
|
||||
result |= i_BIG_ENDIAN_FORMAT_BIT;
|
||||
determinedEndianness = 1;
|
||||
/* Update the start */
|
||||
sampleChannelPtr->offset = sampleByteOffset;
|
||||
} else if (sampleByteOffset == currentByteOffset + currentByteLength) {
|
||||
if (determinedEndianness && (result & i_BIG_ENDIAN_FORMAT_BIT)) {
|
||||
return i_UNSUPPORTED_NONTRIVIAL_ENDIANNESS;
|
||||
}
|
||||
/* All is good, continue little-endian. */
|
||||
determinedEndianness = 1;
|
||||
} else {
|
||||
/* Oh dear. */
|
||||
/* We could be little-endian, but not with any standard format. */
|
||||
/* More likely we've got something weird that we can't support. */
|
||||
return i_UNSUPPORTED_NONTRIVIAL_ENDIANNESS;
|
||||
}
|
||||
/* Remember where we are. */
|
||||
currentByteOffset = sampleByteOffset;
|
||||
currentByteLength = sampleByteLength;
|
||||
/* Accumulate the byte length. */
|
||||
sampleChannelPtr->size += sampleByteLength;
|
||||
/* Assume these are all the same. */
|
||||
*wordBytes = sampleChannelPtr->size;
|
||||
} else {
|
||||
/* Everything is new. Hopefully. */
|
||||
currentChannel = sampleChannel;
|
||||
currentByteOffset = sampleByteOffset;
|
||||
currentByteLength = sampleByteLength;
|
||||
if (sampleChannelPtr->size) {
|
||||
/* Uh-oh, we've seen this channel before. */
|
||||
return i_UNSUPPORTED_NONTRIVIAL_ENDIANNESS;
|
||||
}
|
||||
/* For now, record the byte offset in little-endian terms, */
|
||||
/* because we may not know to reverse it yet. */
|
||||
sampleChannelPtr->offset = sampleByteOffset;
|
||||
sampleChannelPtr->size = sampleByteLength;
|
||||
/* Assume these are all the same. */
|
||||
*wordBytes = sampleByteLength;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
/* Not a packed format. */
|
||||
/* Everything is byte-aligned. */
|
||||
/* Question is whether there multiple samples per channel. */
|
||||
uint32_t currentChannel = ~0U; /* Don't start matched. */
|
||||
uint32_t currentByteOffset = 0;
|
||||
uint32_t currentByteLength = 0;
|
||||
for (sampleCounter = 0; sampleCounter < numSamples; ++sampleCounter) {
|
||||
uint32_t sampleByteOffset = KHR_DFDSVAL(BDFDB, sampleCounter, BITOFFSET) >> 3U;
|
||||
uint32_t sampleByteLength = (KHR_DFDSVAL(BDFDB, sampleCounter, BITLENGTH) + 1) >> 3U;
|
||||
uint32_t sampleChannel = KHR_DFDSVAL(BDFDB, sampleCounter, CHANNELID);
|
||||
InterpretedDFDChannel *sampleChannelPtr;
|
||||
switch (sampleChannel) {
|
||||
case KHR_DF_CHANNEL_RGBSDA_RED:
|
||||
sampleChannelPtr = R;
|
||||
break;
|
||||
case KHR_DF_CHANNEL_RGBSDA_GREEN:
|
||||
sampleChannelPtr = G;
|
||||
break;
|
||||
case KHR_DF_CHANNEL_RGBSDA_BLUE:
|
||||
sampleChannelPtr = B;
|
||||
break;
|
||||
case KHR_DF_CHANNEL_RGBSDA_ALPHA:
|
||||
sampleChannelPtr = A;
|
||||
break;
|
||||
default:
|
||||
return i_UNSUPPORTED_CHANNEL_TYPES;
|
||||
}
|
||||
if (sampleChannel == currentChannel) {
|
||||
/* Continuation of the same channel. */
|
||||
/* Either big-endian, or little-endian with a very large channel. */
|
||||
if (sampleByteOffset == currentByteOffset - 1) { /* One byte earlier */
|
||||
if (determinedEndianness && !(result & i_BIG_ENDIAN_FORMAT_BIT)) {
|
||||
return i_UNSUPPORTED_NONTRIVIAL_ENDIANNESS;
|
||||
}
|
||||
/* All is good, continue big-endian. */
|
||||
result |= i_BIG_ENDIAN_FORMAT_BIT;
|
||||
determinedEndianness = 1;
|
||||
/* Update the start */
|
||||
sampleChannelPtr->offset = sampleByteOffset;
|
||||
} else if (sampleByteOffset == currentByteOffset + currentByteLength) {
|
||||
if (determinedEndianness && (result & i_BIG_ENDIAN_FORMAT_BIT)) {
|
||||
return i_UNSUPPORTED_NONTRIVIAL_ENDIANNESS;
|
||||
}
|
||||
/* All is good, continue little-endian. */
|
||||
determinedEndianness = 1;
|
||||
} else {
|
||||
/* Oh dear. */
|
||||
/* We could be little-endian, but not with any standard format. */
|
||||
/* More likely we've got something weird that we can't support. */
|
||||
return i_UNSUPPORTED_NONTRIVIAL_ENDIANNESS;
|
||||
}
|
||||
/* Remember where we are. */
|
||||
currentByteOffset = sampleByteOffset;
|
||||
currentByteLength = sampleByteLength;
|
||||
/* Accumulate the byte length. */
|
||||
sampleChannelPtr->size += sampleByteLength;
|
||||
/* Assume these are all the same. */
|
||||
*wordBytes = sampleChannelPtr->size;
|
||||
} else {
|
||||
/* Everything is new. Hopefully. */
|
||||
currentChannel = sampleChannel;
|
||||
currentByteOffset = sampleByteOffset;
|
||||
currentByteLength = sampleByteLength;
|
||||
if (sampleChannelPtr->size) {
|
||||
/* Uh-oh, we've seen this channel before. */
|
||||
return i_UNSUPPORTED_NONTRIVIAL_ENDIANNESS;
|
||||
}
|
||||
/* For now, record the byte offset in little-endian terms, */
|
||||
/* because we may not know to reverse it yet. */
|
||||
sampleChannelPtr->offset = sampleByteOffset;
|
||||
sampleChannelPtr->size = sampleByteLength;
|
||||
/* Assume these are all the same. */
|
||||
*wordBytes = sampleByteLength;
|
||||
}
|
||||
}
|
||||
return i_UNSUPPORTED_CHANNEL_TYPES;
|
||||
}
|
||||
|
||||
if (isDepthStencil) {
|
||||
/* For Depth/Stencil formats wordBytes is determined by the required alignment of */
|
||||
/* the larger channel. */
|
||||
uint32_t largerSize = R->size > G->size ? R->size : G->size;
|
||||
*wordBytes = bit_ceil(largerSize);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -5,9 +5,6 @@
|
|||
Automatically generated by makevk2dfd.pl.
|
||||
*************************************************************************/
|
||||
|
||||
/* Vulkan combined depth & stencil formats are not included here
|
||||
* because they do not exist outside a Vulkan device.
|
||||
*/
|
||||
case VK_FORMAT_R4G4_UNORM_PACK8: {
|
||||
int channels[] = {1,0}; int bits[] = {4,4};
|
||||
return createDFDPacked(0, 2, bits, channels, s_UNORM);
|
||||
|
@ -222,6 +219,9 @@ case VK_FORMAT_D16_UNORM: return createDFDDepthStencil(16,0,2);
|
|||
case VK_FORMAT_X8_D24_UNORM_PACK32: return createDFDDepthStencil(24,0,4);
|
||||
case VK_FORMAT_D32_SFLOAT: return createDFDDepthStencil(32,0,4);
|
||||
case VK_FORMAT_S8_UINT: return createDFDDepthStencil(0,8,1);
|
||||
case VK_FORMAT_D16_UNORM_S8_UINT: return createDFDDepthStencil(16,8,4);
|
||||
case VK_FORMAT_D24_UNORM_S8_UINT: return createDFDDepthStencil(24,8,4);
|
||||
case VK_FORMAT_D32_SFLOAT_S8_UINT: return createDFDDepthStencil(32,8,8);
|
||||
case VK_FORMAT_BC1_RGB_UNORM_BLOCK: return createDFDCompressed(c_BC1_RGB, 4, 4, 1, s_UNORM);
|
||||
case VK_FORMAT_BC1_RGB_SRGB_BLOCK: return createDFDCompressed(c_BC1_RGB, 4, 4, 1, s_SRGB);
|
||||
case VK_FORMAT_BC1_RGBA_UNORM_BLOCK: return createDFDCompressed(c_BC1_RGBA, 4, 4, 1, s_UNORM);
|
||||
|
@ -276,6 +276,92 @@ case VK_FORMAT_ASTC_12x10_UNORM_BLOCK: return createDFDCompressed(c_ASTC, 12, 10
|
|||
case VK_FORMAT_ASTC_12x10_SRGB_BLOCK: return createDFDCompressed(c_ASTC, 12, 10, 1, s_SRGB);
|
||||
case VK_FORMAT_ASTC_12x12_UNORM_BLOCK: return createDFDCompressed(c_ASTC, 12, 12, 1, s_UNORM);
|
||||
case VK_FORMAT_ASTC_12x12_SRGB_BLOCK: return createDFDCompressed(c_ASTC, 12, 12, 1, s_SRGB);
|
||||
case VK_FORMAT_G8B8G8R8_422_UNORM: {
|
||||
int channels[] = {0, 1, 0, 2}; int bits[] = {8, 8, 8, 8}; int paddings[] = {0, 0, 0, 0};
|
||||
int position_xs[] = {64, 64, 192, 64}; int position_ys[] = {128, 128, 128, 128};
|
||||
return createDFD422(0, 4, bits, paddings, channels, position_xs, position_ys, s_UNORM);
|
||||
}
|
||||
case VK_FORMAT_B8G8R8G8_422_UNORM: {
|
||||
int channels[] = {1, 0, 2, 0}; int bits[] = {8, 8, 8, 8}; int paddings[] = {0, 0, 0, 0};
|
||||
int position_xs[] = {64, 64, 64, 192}; int position_ys[] = {128, 128, 128, 128};
|
||||
return createDFD422(0, 4, bits, paddings, channels, position_xs, position_ys, s_UNORM);
|
||||
}
|
||||
case VK_FORMAT_R10X6_UNORM_PACK16: {
|
||||
int channels[] = {0}; int bits[] = {10}; int paddings[] = {6};
|
||||
return createDFDPackedPadded(0, 1, bits, paddings, channels, s_UNORM);
|
||||
}
|
||||
case VK_FORMAT_R10X6G10X6_UNORM_2PACK16: {
|
||||
int channels[] = {0, 1}; int bits[] = {10, 10}; int paddings[] = {6, 6};
|
||||
return createDFDPackedPadded(0, 2, bits, paddings, channels, s_UNORM);
|
||||
}
|
||||
case VK_FORMAT_R10X6G10X6B10X6A10X6_UNORM_4PACK16: {
|
||||
int channels[] = {0, 1, 2, 3}; int bits[] = {10, 10, 10, 10}; int paddings[] = {6, 6, 6, 6};
|
||||
return createDFDPackedPadded(0, 4, bits, paddings, channels, s_UNORM);
|
||||
}
|
||||
case VK_FORMAT_G10X6B10X6G10X6R10X6_422_UNORM_4PACK16: {
|
||||
int channels[] = {0, 1, 0, 2}; int bits[] = {10, 10, 10, 10}; int paddings[] = {6, 6, 6, 6};
|
||||
int position_xs[] = {64, 64, 192, 64}; int position_ys[] = {128, 128, 128, 128};
|
||||
return createDFD422(0, 4, bits, paddings, channels, position_xs, position_ys, s_UNORM);
|
||||
}
|
||||
case VK_FORMAT_B10X6G10X6R10X6G10X6_422_UNORM_4PACK16: {
|
||||
int channels[] = {1, 0, 2, 0}; int bits[] = {10, 10, 10, 10}; int paddings[] = {6, 6, 6, 6};
|
||||
int position_xs[] = {64, 64, 64, 192}; int position_ys[] = {128, 128, 128, 128};
|
||||
return createDFD422(0, 4, bits, paddings, channels, position_xs, position_ys, s_UNORM);
|
||||
}
|
||||
case VK_FORMAT_R12X4_UNORM_PACK16: {
|
||||
int channels[] = {0}; int bits[] = {12}; int paddings[] = {4};
|
||||
return createDFDPackedPadded(0, 1, bits, paddings, channels, s_UNORM);
|
||||
}
|
||||
case VK_FORMAT_R12X4G12X4_UNORM_2PACK16: {
|
||||
int channels[] = {0, 1}; int bits[] = {12, 12}; int paddings[] = {4, 4};
|
||||
return createDFDPackedPadded(0, 2, bits, paddings, channels, s_UNORM);
|
||||
}
|
||||
case VK_FORMAT_R12X4G12X4B12X4A12X4_UNORM_4PACK16: {
|
||||
int channels[] = {0, 1, 2, 3}; int bits[] = {12, 12, 12, 12}; int paddings[] = {4, 4, 4, 4};
|
||||
return createDFDPackedPadded(0, 4, bits, paddings, channels, s_UNORM);
|
||||
}
|
||||
case VK_FORMAT_G12X4B12X4G12X4R12X4_422_UNORM_4PACK16: {
|
||||
int channels[] = {0, 1, 0, 2}; int bits[] = {12, 12, 12, 12}; int paddings[] = {4, 4, 4, 4};
|
||||
int position_xs[] = {64, 64, 192, 64}; int position_ys[] = {128, 128, 128, 128};
|
||||
return createDFD422(0, 4, bits, paddings, channels, position_xs, position_ys, s_UNORM);
|
||||
}
|
||||
case VK_FORMAT_B12X4G12X4R12X4G12X4_422_UNORM_4PACK16: {
|
||||
int channels[] = {1, 0, 2, 0}; int bits[] = {12, 12, 12, 12}; int paddings[] = {4, 4, 4, 4};
|
||||
int position_xs[] = {64, 64, 64, 192}; int position_ys[] = {128, 128, 128, 128};
|
||||
return createDFD422(0, 4, bits, paddings, channels, position_xs, position_ys, s_UNORM);
|
||||
}
|
||||
case VK_FORMAT_G16B16G16R16_422_UNORM: {
|
||||
int channels[] = {0, 1, 0, 2}; int bits[] = {16, 16, 16, 16}; int paddings[] = {0, 0, 0, 0};
|
||||
int position_xs[] = {64, 64, 192, 64}; int position_ys[] = {128, 128, 128, 128};
|
||||
return createDFD422(0, 4, bits, paddings, channels, position_xs, position_ys, s_UNORM);
|
||||
}
|
||||
case VK_FORMAT_B16G16R16G16_422_UNORM: {
|
||||
int channels[] = {1, 0, 2, 0}; int bits[] = {16, 16, 16, 16}; int paddings[] = {0, 0, 0, 0};
|
||||
int position_xs[] = {64, 64, 64, 192}; int position_ys[] = {128, 128, 128, 128};
|
||||
return createDFD422(0, 4, bits, paddings, channels, position_xs, position_ys, s_UNORM);
|
||||
}
|
||||
case VK_FORMAT_A4R4G4B4_UNORM_PACK16: {
|
||||
int channels[] = {2,1,0,3}; int bits[] = {4,4,4,4};
|
||||
return createDFDPacked(0, 4, bits, channels, s_UNORM);
|
||||
}
|
||||
case VK_FORMAT_A4B4G4R4_UNORM_PACK16: {
|
||||
int channels[] = {0,1,2,3}; int bits[] = {4,4,4,4};
|
||||
return createDFDPacked(0, 4, bits, channels, s_UNORM);
|
||||
}
|
||||
case VK_FORMAT_ASTC_4x4_SFLOAT_BLOCK: return createDFDCompressed(c_ASTC, 4, 4, 1, s_SFLOAT);
|
||||
case VK_FORMAT_ASTC_5x4_SFLOAT_BLOCK: return createDFDCompressed(c_ASTC, 5, 4, 1, s_SFLOAT);
|
||||
case VK_FORMAT_ASTC_5x5_SFLOAT_BLOCK: return createDFDCompressed(c_ASTC, 5, 5, 1, s_SFLOAT);
|
||||
case VK_FORMAT_ASTC_6x5_SFLOAT_BLOCK: return createDFDCompressed(c_ASTC, 6, 5, 1, s_SFLOAT);
|
||||
case VK_FORMAT_ASTC_6x6_SFLOAT_BLOCK: return createDFDCompressed(c_ASTC, 6, 6, 1, s_SFLOAT);
|
||||
case VK_FORMAT_ASTC_8x5_SFLOAT_BLOCK: return createDFDCompressed(c_ASTC, 8, 5, 1, s_SFLOAT);
|
||||
case VK_FORMAT_ASTC_8x6_SFLOAT_BLOCK: return createDFDCompressed(c_ASTC, 8, 6, 1, s_SFLOAT);
|
||||
case VK_FORMAT_ASTC_8x8_SFLOAT_BLOCK: return createDFDCompressed(c_ASTC, 8, 8, 1, s_SFLOAT);
|
||||
case VK_FORMAT_ASTC_10x5_SFLOAT_BLOCK: return createDFDCompressed(c_ASTC, 10, 5, 1, s_SFLOAT);
|
||||
case VK_FORMAT_ASTC_10x6_SFLOAT_BLOCK: return createDFDCompressed(c_ASTC, 10, 6, 1, s_SFLOAT);
|
||||
case VK_FORMAT_ASTC_10x8_SFLOAT_BLOCK: return createDFDCompressed(c_ASTC, 10, 8, 1, s_SFLOAT);
|
||||
case VK_FORMAT_ASTC_10x10_SFLOAT_BLOCK: return createDFDCompressed(c_ASTC, 10, 10, 1, s_SFLOAT);
|
||||
case VK_FORMAT_ASTC_12x10_SFLOAT_BLOCK: return createDFDCompressed(c_ASTC, 12, 10, 1, s_SFLOAT);
|
||||
case VK_FORMAT_ASTC_12x12_SFLOAT_BLOCK: return createDFDCompressed(c_ASTC, 12, 12, 1, s_SFLOAT);
|
||||
case VK_FORMAT_PVRTC1_2BPP_UNORM_BLOCK_IMG: return createDFDCompressed(c_PVRTC, 8, 4, 1, s_UNORM);
|
||||
case VK_FORMAT_PVRTC1_4BPP_UNORM_BLOCK_IMG: return createDFDCompressed(c_PVRTC, 4, 4, 1, s_UNORM);
|
||||
case VK_FORMAT_PVRTC2_2BPP_UNORM_BLOCK_IMG: return createDFDCompressed(c_PVRTC2, 8, 4, 1, s_UNORM);
|
||||
|
@ -284,20 +370,6 @@ 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);
|
||||
case VK_FORMAT_PVRTC2_4BPP_SRGB_BLOCK_IMG: return createDFDCompressed(c_PVRTC2, 4, 4, 1, s_SRGB);
|
||||
case VK_FORMAT_ASTC_4x4_SFLOAT_BLOCK_EXT: return createDFDCompressed(c_ASTC, 4, 4, 1, s_SFLOAT);
|
||||
case VK_FORMAT_ASTC_5x4_SFLOAT_BLOCK_EXT: return createDFDCompressed(c_ASTC, 5, 4, 1, s_SFLOAT);
|
||||
case VK_FORMAT_ASTC_5x5_SFLOAT_BLOCK_EXT: return createDFDCompressed(c_ASTC, 5, 5, 1, s_SFLOAT);
|
||||
case VK_FORMAT_ASTC_6x5_SFLOAT_BLOCK_EXT: return createDFDCompressed(c_ASTC, 6, 5, 1, s_SFLOAT);
|
||||
case VK_FORMAT_ASTC_6x6_SFLOAT_BLOCK_EXT: return createDFDCompressed(c_ASTC, 6, 6, 1, s_SFLOAT);
|
||||
case VK_FORMAT_ASTC_8x5_SFLOAT_BLOCK_EXT: return createDFDCompressed(c_ASTC, 8, 5, 1, s_SFLOAT);
|
||||
case VK_FORMAT_ASTC_8x6_SFLOAT_BLOCK_EXT: return createDFDCompressed(c_ASTC, 8, 6, 1, s_SFLOAT);
|
||||
case VK_FORMAT_ASTC_8x8_SFLOAT_BLOCK_EXT: return createDFDCompressed(c_ASTC, 8, 8, 1, s_SFLOAT);
|
||||
case VK_FORMAT_ASTC_10x5_SFLOAT_BLOCK_EXT: return createDFDCompressed(c_ASTC, 10, 5, 1, s_SFLOAT);
|
||||
case VK_FORMAT_ASTC_10x6_SFLOAT_BLOCK_EXT: return createDFDCompressed(c_ASTC, 10, 6, 1, s_SFLOAT);
|
||||
case VK_FORMAT_ASTC_10x8_SFLOAT_BLOCK_EXT: return createDFDCompressed(c_ASTC, 10, 8, 1, s_SFLOAT);
|
||||
case VK_FORMAT_ASTC_10x10_SFLOAT_BLOCK_EXT: return createDFDCompressed(c_ASTC, 10, 10, 1, s_SFLOAT);
|
||||
case VK_FORMAT_ASTC_12x10_SFLOAT_BLOCK_EXT: return createDFDCompressed(c_ASTC, 12, 10, 1, s_SFLOAT);
|
||||
case VK_FORMAT_ASTC_12x12_SFLOAT_BLOCK_EXT: return createDFDCompressed(c_ASTC, 12, 12, 1, s_SFLOAT);
|
||||
#if 0
|
||||
case VK_FORMAT_ASTC_3x3x3_UNORM_BLOCK_EXT: return createDFDCompressed(c_ASTC, 3, 3, 3, s_UNORM);
|
||||
case VK_FORMAT_ASTC_3x3x3_SRGB_BLOCK_EXT: return createDFDCompressed(c_ASTC, 3, 3, 3, s_SRGB);
|
||||
|
@ -330,11 +402,8 @@ 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_A4R4G4B4_UNORM_PACK16_EXT: {
|
||||
int channels[] = {2,1,0,3}; int bits[] = {4,4,4,4};
|
||||
return createDFDPacked(0, 4, bits, channels, s_UNORM);
|
||||
}
|
||||
case VK_FORMAT_A4B4G4R4_UNORM_PACK16_EXT: {
|
||||
int channels[] = {0,1,2,3}; int bits[] = {4,4,4,4};
|
||||
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);
|
||||
}
|
||||
case VK_FORMAT_A8_UNORM_KHR: return createDFDAlpha(0, 1, s_UNORM);
|
||||
|
|
|
@ -307,15 +307,17 @@ KTX_error_code ktxFileStream_getsize(ktxStream* str, ktx_size_t* size)
|
|||
|
||||
assert(str->type == eStreamTypeFile);
|
||||
|
||||
// Need to flush so that fstat will return the current size.
|
||||
// Can ignore return value. The only error that can happen is to tell you
|
||||
// it was a NOP because the file is read only.
|
||||
// Need to flush so that fstat will return the current size.
|
||||
// Can ignore return value. The only error that can happen is to tell you
|
||||
// it was a NOP because the file is read only.
|
||||
#if (defined(_MSC_VER) && _MSC_VER < 1900) || defined(__MINGW64__) && !defined(_UCRT)
|
||||
// Bug in VS2013 msvcrt. fflush on FILE open for READ changes file offset
|
||||
// to 4096.
|
||||
if (str->data.file->_flag & _IOWRT)
|
||||
#endif
|
||||
// Bug in VS2013 msvcrt. fflush on FILE open for READ changes file offset
|
||||
// to 4096.
|
||||
if (str->data.file->_flag & _IOWRT)
|
||||
(void)fflush(str->data.file);
|
||||
#else
|
||||
(void)fflush(str->data.file);
|
||||
#endif
|
||||
statret = fstat(fileno(str->data.file), &statbuf);
|
||||
if (statret < 0) {
|
||||
switch (errno) {
|
||||
|
|
|
@ -27,6 +27,7 @@ typedef enum ktxFormatSizeFlagBits {
|
|||
KTX_FORMAT_SIZE_PALETTIZED_BIT = 0x00000004,
|
||||
KTX_FORMAT_SIZE_DEPTH_BIT = 0x00000008,
|
||||
KTX_FORMAT_SIZE_STENCIL_BIT = 0x00000010,
|
||||
KTX_FORMAT_SIZE_YUVSDA_BIT = 0x00000020,
|
||||
} ktxFormatSizeFlagBits;
|
||||
|
||||
typedef ktx_uint32_t ktxFormatSizeFlags;
|
||||
|
|
|
@ -92,9 +92,9 @@ MODIFICATIONS for use in libktx
|
|||
#include "vkformat_enum.h"
|
||||
|
||||
#if defined(_WIN32) && !defined(__MINGW32__)
|
||||
#ifndef NOMINMAX
|
||||
#if !defined(NOMINMAX)
|
||||
#define NOMINMAX
|
||||
#endif
|
||||
#endif // !defined(NOMINMAX)
|
||||
#ifndef __cplusplus
|
||||
#undef inline
|
||||
#define inline __inline
|
||||
|
|
|
@ -525,14 +525,38 @@ ktxHashList_Deserialize(ktxHashList* pHead, unsigned int kvdLen, void* pKvd)
|
|||
|
||||
result = KTX_SUCCESS;
|
||||
while (result == KTX_SUCCESS && src < (char *)pKvd + kvdLen) {
|
||||
if (src + 6 > (char *)pKvd + kvdLen) {
|
||||
// Not enough space for another entry
|
||||
return KTX_FILE_DATA_ERROR;
|
||||
}
|
||||
|
||||
char* key;
|
||||
unsigned int keyLen, valueLen;
|
||||
void* value;
|
||||
ktx_uint32_t keyAndValueByteSize = *((ktx_uint32_t*)src);
|
||||
|
||||
if (src + 4 + keyAndValueByteSize > (char *)pKvd + kvdLen) {
|
||||
// Not enough space for this entry
|
||||
return KTX_FILE_DATA_ERROR;
|
||||
}
|
||||
|
||||
src += sizeof(keyAndValueByteSize);
|
||||
key = src;
|
||||
keyLen = (unsigned int)strlen(key) + 1;
|
||||
keyLen = 0;
|
||||
|
||||
while (keyLen < keyAndValueByteSize && key[keyLen] != '\0') keyLen++;
|
||||
|
||||
if (key[keyLen] != '\0') {
|
||||
// Missing NULL terminator
|
||||
return KTX_FILE_DATA_ERROR;
|
||||
}
|
||||
|
||||
if (keyLen >= 3 && key[0] == '\xEF' && key[1] == '\xBB' && key[2] == '\xBF') {
|
||||
// Forbidden BOM
|
||||
return KTX_FILE_DATA_ERROR;
|
||||
}
|
||||
|
||||
keyLen += 1;
|
||||
value = key + keyLen;
|
||||
|
||||
valueLen = keyAndValueByteSize - keyLen;
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/* -*- tab-width: 4; -*- */
|
||||
/* vi: set sw=2 ts=4 expandtab: */
|
||||
|
||||
/* $Id: e36ad79b5eac8ea237d6a05602c71aadab575519 $ */
|
||||
/* $Id$ */
|
||||
|
||||
/*
|
||||
* Copyright 2010-2020 The Khronos Group Inc.
|
||||
|
@ -29,6 +29,9 @@
|
|||
#ifndef MAX
|
||||
#define MAX(x, y) (((x) > (y)) ? (x) : (y))
|
||||
#endif
|
||||
#ifndef MIN
|
||||
#define MIN(x, y) (((x) < (y)) ? (x) : (y))
|
||||
#endif
|
||||
|
||||
#define QUOTE(x) #x
|
||||
#define STR(x) QUOTE(x)
|
||||
|
@ -211,6 +214,37 @@ KTX_error_code _ktxUnpackETC(const GLubyte* srcETC, const GLenum srcFormat,
|
|||
GLenum* format, GLenum* internalFormat, GLenum* type,
|
||||
GLint R16Formats, GLboolean supportsSRGB);
|
||||
|
||||
/*
|
||||
* @internal
|
||||
* ktxCompressZLIBBounds
|
||||
*
|
||||
* Returns upper bound for compresses data using miniz (ZLIB)
|
||||
*/
|
||||
ktx_size_t ktxCompressZLIBBounds(ktx_size_t srcLength);
|
||||
|
||||
/*
|
||||
* @internal
|
||||
* ktxCompressZLIBInt
|
||||
*
|
||||
* Compresses data using miniz (ZLIB)
|
||||
*/
|
||||
KTX_error_code ktxCompressZLIBInt(unsigned char* pDest,
|
||||
ktx_size_t* pDestLength,
|
||||
const unsigned char* pSrc,
|
||||
ktx_size_t srcLength,
|
||||
ktx_uint32_t level);
|
||||
|
||||
/*
|
||||
* @internal
|
||||
* ktxUncompressZLIBInt
|
||||
*
|
||||
* Uncompresses data using miniz (ZLIB)
|
||||
*/
|
||||
KTX_error_code ktxUncompressZLIBInt(unsigned char* pDest,
|
||||
ktx_size_t* pDestLength,
|
||||
const unsigned char* pSrc,
|
||||
ktx_size_t srcLength);
|
||||
|
||||
/*
|
||||
* Pad nbytes to next multiple of n
|
||||
*/
|
||||
|
@ -257,7 +291,55 @@ KTX_error_code _ktxUnpackETC(const GLubyte* srcETC, const GLenum srcFormat,
|
|||
======================================
|
||||
*/
|
||||
|
||||
void printKTX2Info2(ktxStream* src, KTX_header2* header);
|
||||
KTX_error_code printKTX2Info2(ktxStream* src, KTX_header2* header);
|
||||
|
||||
/*
|
||||
* fopen a file identified by a UTF-8 path.
|
||||
*/
|
||||
#if defined(_WIN32)
|
||||
#ifndef WIN32_LEAN_AND_MEAN
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#endif
|
||||
#ifndef NOMINMAX
|
||||
#define NOMINMAX
|
||||
#endif
|
||||
#include <assert.h>
|
||||
#include <windows.h>
|
||||
#include <shellapi.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
// For Windows, we convert the UTF-8 path and mode to UTF-16 path and use
|
||||
// _wfopen which correctly handles unicode characters.
|
||||
static inline FILE* ktxFOpenUTF8(char const* path, char const* mode) {
|
||||
int wpLen = MultiByteToWideChar(CP_UTF8, 0, path, -1, NULL, 0);
|
||||
int wmLen = MultiByteToWideChar(CP_UTF8, 0, mode, -1, NULL, 0);
|
||||
FILE* fp = NULL;
|
||||
if (wpLen > 0 && wmLen > 0)
|
||||
{
|
||||
wchar_t* wpath = (wchar_t*)malloc(wpLen * sizeof(wchar_t));
|
||||
wchar_t* wmode = (wchar_t*)malloc(wmLen * sizeof(wchar_t));
|
||||
MultiByteToWideChar(CP_UTF8, 0, path, -1, wpath, wpLen);
|
||||
MultiByteToWideChar(CP_UTF8, 0, mode, -1, wmode, wmLen);
|
||||
// Returned errno_t value is also set in the global errno.
|
||||
// Apps use that for error detail as libktx only returns
|
||||
// KTX_FILE_OPEN_FAILED.
|
||||
(void)_wfopen_s(&fp, wpath, wmode);
|
||||
free(wpath);
|
||||
free(wmode);
|
||||
return fp;
|
||||
} else {
|
||||
assert(KTX_FALSE
|
||||
&& "ktxFOpenUTF8 called with zero length path or mode.");
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
#else
|
||||
// For other platforms there is no need for any conversion, they
|
||||
// support UTF-8 natively.
|
||||
static inline FILE* ktxFOpenUTF8(char const* path, char const* mode) {
|
||||
return fopen(path, mode);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -0,0 +1,149 @@
|
|||
/* -*- tab-width: 4; -*- */
|
||||
/* vi: set sw=2 ts=4 expandtab: */
|
||||
|
||||
/*
|
||||
* Copyright 2023-2023 The Khronos Group Inc.
|
||||
* Copyright 2023-2023 RasterGrid Kft.
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
/**
|
||||
* @internal
|
||||
* @file miniz_wrapper.c
|
||||
* @~English
|
||||
*
|
||||
* @brief Wrapper functions for ZLIB compression/decompression using miniz.
|
||||
*
|
||||
* @author Daniel Rakos, RasterGrid
|
||||
*/
|
||||
|
||||
#include "ktx.h"
|
||||
#include "ktxint.h"
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
#if !KTX_FEATURE_WRITE
|
||||
// The reader does not link with the basisu components that already include a
|
||||
// definition of miniz so we include it here explicitly.
|
||||
#ifdef __GNUC__
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wextra"
|
||||
#pragma GCC diagnostic ignored "-Wmisleading-indentation"
|
||||
#endif
|
||||
#include "encoder/basisu_miniz.h"
|
||||
#ifdef __GNUC__
|
||||
#pragma GCC diagnostic pop
|
||||
#endif
|
||||
#else
|
||||
// Otherwise we only declare the interfaces and link with the basisu version.
|
||||
// This is needed because while miniz is defined as a header in basisu it's
|
||||
// not declaring the functions as static or inline, hence causing multiple
|
||||
// conflicting definitions at link-time.
|
||||
namespace buminiz {
|
||||
typedef unsigned long mz_ulong;
|
||||
enum { MZ_OK = 0, MZ_STREAM_END = 1, MZ_NEED_DICT = 2, MZ_ERRNO = -1, MZ_STREAM_ERROR = -2, MZ_DATA_ERROR = -3, MZ_MEM_ERROR = -4, MZ_BUF_ERROR = -5, MZ_VERSION_ERROR = -6, MZ_PARAM_ERROR = -10000 };
|
||||
mz_ulong mz_compressBound(mz_ulong source_len);
|
||||
int mz_compress2(unsigned char *pDest, mz_ulong *pDest_len, const unsigned char *pSource, mz_ulong source_len, int level);
|
||||
int mz_uncompress(unsigned char *pDest, mz_ulong *pDest_len, const unsigned char *pSource, mz_ulong source_len);
|
||||
}
|
||||
#endif
|
||||
|
||||
using namespace buminiz;
|
||||
|
||||
extern "C" {
|
||||
|
||||
/**
|
||||
* @internal
|
||||
* @~English
|
||||
* @brief Returns upper bound for compresses data using miniz (ZLIB).
|
||||
*
|
||||
* @param srcLength source data length
|
||||
*
|
||||
* @author Daniel Rakos, RasterGrid
|
||||
*/
|
||||
ktx_size_t ktxCompressZLIBBounds(ktx_size_t srcLength) {
|
||||
return mz_compressBound((mz_ulong)srcLength);
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
* @~English
|
||||
* @brief Compresses data using miniz (ZLIB)
|
||||
*
|
||||
* @param pDest destination data buffer
|
||||
* @param pDestLength destination data buffer size
|
||||
* (filled with written byte count on success)
|
||||
* @param pSrc source data buffer
|
||||
* @param srcLength source data size
|
||||
* @param level compression level (between 1 and 9)
|
||||
*
|
||||
* @author Daniel Rakos, RasterGrid
|
||||
*/
|
||||
KTX_error_code ktxCompressZLIBInt(unsigned char* pDest,
|
||||
ktx_size_t* pDestLength,
|
||||
const unsigned char* pSrc,
|
||||
ktx_size_t srcLength,
|
||||
ktx_uint32_t level) {
|
||||
if ((srcLength | *pDestLength) > 0xFFFFFFFFU) return KTX_INVALID_VALUE;
|
||||
mz_ulong mzCompressedSize = (mz_ulong)*pDestLength;
|
||||
int status = mz_compress2(pDest, &mzCompressedSize, pSrc, (mz_ulong)srcLength, level);
|
||||
switch (status) {
|
||||
case MZ_OK:
|
||||
*pDestLength = mzCompressedSize;
|
||||
return KTX_SUCCESS;
|
||||
case MZ_PARAM_ERROR:
|
||||
return KTX_INVALID_VALUE;
|
||||
case MZ_BUF_ERROR:
|
||||
#ifdef DEBUG
|
||||
assert(false && "Deflate dstSize too small.");
|
||||
#endif
|
||||
return KTX_OUT_OF_MEMORY;
|
||||
case MZ_MEM_ERROR:
|
||||
#ifdef DEBUG
|
||||
assert(false && "Deflate workspace too small.");
|
||||
#endif
|
||||
return KTX_OUT_OF_MEMORY;
|
||||
default:
|
||||
// The remaining errors look like they should only
|
||||
// occur during decompression but just in case.
|
||||
#ifdef DEBUG
|
||||
assert(true);
|
||||
#endif
|
||||
return KTX_INVALID_OPERATION;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
* @~English
|
||||
* @brief Uncompresses data using miniz (ZLIB)
|
||||
*
|
||||
* @param pDest destination data buffer
|
||||
* @param pDestLength destination data buffer size
|
||||
* (filled with written byte count on success)
|
||||
* @param pSrc source data buffer
|
||||
* @param srcLength source data size
|
||||
*
|
||||
* @author Daniel Rakos, RasterGrid
|
||||
*/
|
||||
KTX_error_code ktxUncompressZLIBInt(unsigned char* pDest,
|
||||
ktx_size_t* pDestLength,
|
||||
const unsigned char* pSrc,
|
||||
ktx_size_t srcLength) {
|
||||
if ((srcLength | *pDestLength) > 0xFFFFFFFFU) return KTX_INVALID_VALUE;
|
||||
mz_ulong mzUncompressedSize = (mz_ulong)*pDestLength;
|
||||
int status = mz_uncompress(pDest, &mzUncompressedSize, pSrc, (mz_ulong)srcLength);
|
||||
switch (status) {
|
||||
case MZ_OK:
|
||||
*pDestLength = mzUncompressedSize;
|
||||
return KTX_SUCCESS;
|
||||
case MZ_BUF_ERROR:
|
||||
return KTX_DECOMPRESS_LENGTH_ERROR; // buffer too small
|
||||
case MZ_MEM_ERROR:
|
||||
return KTX_OUT_OF_MEMORY;
|
||||
default:
|
||||
return KTX_FILE_DATA_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -1,7 +1,7 @@
|
|||
/* -*- tab-width: 4; -*- */
|
||||
/* vi: set sw=2 ts=4 expandtab: */
|
||||
|
||||
/* $Id: 02ea6de2d8db512ca3af08f48b98ab5f6c35e7e5 $ */
|
||||
/* $Id$ */
|
||||
|
||||
/*
|
||||
* Copyright 2010-2020 The Khronos Group Inc.
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
|
||||
/**
|
||||
* @internal
|
||||
* @file writer.c
|
||||
* @file texture.c
|
||||
* @~English
|
||||
*
|
||||
* @brief ktxTexture implementation.
|
||||
|
@ -305,10 +305,13 @@ ktxDetermineFileType_(ktxStream* pStream, ktxFileType_* pFileType,
|
|||
/**
|
||||
* @memberof ktxTexture
|
||||
* @~English
|
||||
* @brief Construct (initialize) a ktx1 or ktx2 texture according to the stream
|
||||
* @brief Create a ktx1 or ktx2 texture according to the stream
|
||||
* data.
|
||||
*
|
||||
* @copydetails ktxTexture_CreateFromStdioStream
|
||||
* See @ref ktxTexture1::ktxTexture1_CreateFromStream
|
||||
* "ktxTexture1_CreateFromStream" or
|
||||
* @ref ktxTexture2::ktxTexture2_CreateFromStream
|
||||
* "ktxTexture2_CreateFromStream" for details.
|
||||
*/
|
||||
KTX_error_code
|
||||
ktxTexture_CreateFromStream(ktxStream* pStream,
|
||||
|
@ -359,7 +362,10 @@ ktxTexture_CreateFromStream(ktxStream* pStream,
|
|||
* @brief Create a ktxTexture1 or ktxTexture2 from a stdio stream according
|
||||
* to the stream data.
|
||||
*
|
||||
* @copydetails ktxTexture1_CreateFromStdioStream()
|
||||
* See @ref ktxTexture1::ktxTexture1_CreateFromStdioStream
|
||||
* "ktxTexture1_CreateFromStdioStream" or
|
||||
* @ref ktxTexture2::ktxTexture2_CreateFromStdioStream
|
||||
* "ktxTexture2_CreateFromStdioStream" for details.
|
||||
*/
|
||||
KTX_error_code
|
||||
ktxTexture_CreateFromStdioStream(FILE* stdioStream,
|
||||
|
@ -385,29 +391,10 @@ ktxTexture_CreateFromStdioStream(FILE* stdioStream,
|
|||
* @brief Create a ktxTexture1 or ktxTexture2 from a named KTX file according
|
||||
* to the file contents.
|
||||
*
|
||||
* The address of a newly created ktxTexture reflecting the contents of the
|
||||
* file is written to the location pointed at by @p newTex.
|
||||
*
|
||||
* The create flag KTX_TEXTURE_CREATE_LOAD_IMAGE_DATA_BIT should not be set,
|
||||
* if the ktxTexture is ultimately to be uploaded to OpenGL or Vulkan. This
|
||||
* will minimize memory usage by allowing, for example, loading the images
|
||||
* directly from the source into a Vulkan staging buffer.
|
||||
*
|
||||
* The create flag KTX_TEXTURE_CREATE_RAW_KVDATA_BIT should not be used. It is
|
||||
* provided solely to enable implementation of the @e libktx v1 API on top of
|
||||
* ktxTexture.
|
||||
*
|
||||
* @param[in] filename pointer to a char array containing the file name.
|
||||
* @param[in] createFlags bitmask requesting specific actions during creation.
|
||||
* @param[in,out] newTex pointer to a location in which store the address of
|
||||
* the newly created texture.
|
||||
*
|
||||
* @return KTX_SUCCESS on success, other KTX_* enum values on error.
|
||||
|
||||
* @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().
|
||||
* See @ref ktxTexture1::ktxTexture1_CreateFromNamedFile
|
||||
* "ktxTexture1_CreateFromNamedFile" or
|
||||
* @ref ktxTexture2::ktxTexture2_CreateFromNamedFile
|
||||
* "ktxTexture2_CreateFromNamedFile" for details.
|
||||
*/
|
||||
KTX_error_code
|
||||
ktxTexture_CreateFromNamedFile(const char* const filename,
|
||||
|
@ -421,7 +408,7 @@ ktxTexture_CreateFromNamedFile(const char* const filename,
|
|||
if (filename == NULL || newTex == NULL)
|
||||
return KTX_INVALID_VALUE;
|
||||
|
||||
file = fopen(filename, "rb");
|
||||
file = ktxFOpenUTF8(filename, "rb");
|
||||
if (!file)
|
||||
return KTX_FILE_OPEN_FAILED;
|
||||
|
||||
|
@ -438,29 +425,10 @@ ktxTexture_CreateFromNamedFile(const char* const filename,
|
|||
* @brief Create a ktxTexture1 or ktxTexture2 from KTX-formatted data in memory
|
||||
* according to the data contents.
|
||||
*
|
||||
* The address of a newly created ktxTexture reflecting the contents of the
|
||||
* serialized KTX data is written to the location pointed at by @p newTex.
|
||||
*
|
||||
* The create flag KTX_TEXTURE_CREATE_LOAD_IMAGE_DATA_BIT should not be set,
|
||||
* if the ktxTexture is ultimately to be uploaded to OpenGL or Vulkan. This
|
||||
* will minimize memory usage by allowing, for example, loading the images
|
||||
* directly from the source into a Vulkan staging buffer.
|
||||
*
|
||||
* The create flag KTX_TEXTURE_CREATE_RAW_KVDATA_BIT should not be used. It is
|
||||
* provided solely to enable implementation of the @e libktx v1 API on top of
|
||||
* ktxTexture.
|
||||
*
|
||||
* @param[in] bytes pointer to the memory containing the serialized KTX data.
|
||||
* @param[in] size length of the KTX data in bytes.
|
||||
* @param[in] createFlags bitmask requesting specific actions during creation.
|
||||
* @param[in,out] newTex pointer to a location in which store the address of
|
||||
* the newly created texture.
|
||||
*
|
||||
* @return KTX_SUCCESS on success, other KTX_* enum values on error.
|
||||
*
|
||||
* @exception KTX_INVALID_VALUE Either @p bytes is NULL or @p size is 0.
|
||||
*
|
||||
* For other exceptions, see ktxTexture_CreateFromStdioStream().
|
||||
* See @ref ktxTexture1::ktxTexture1_CreateFromMemory
|
||||
* "ktxTexture1_CreateFromMemory" or
|
||||
* @ref ktxTexture2::ktxTexture2_CreateFromMemory
|
||||
* "ktxTexture2_CreateFromMemory" for details.
|
||||
*/
|
||||
KTX_error_code
|
||||
ktxTexture_CreateFromMemory(const ktx_uint8_t* bytes, ktx_size_t size,
|
||||
|
@ -567,7 +535,7 @@ ktxTexture_calcImageSize(ktxTexture* This, ktx_uint32_t level,
|
|||
blockCount.y
|
||||
= (ktx_uint32_t)ceilf(levelHeight / prtctd->_formatSize.blockHeight);
|
||||
blockCount.x = MAX(prtctd->_formatSize.minBlocksX, blockCount.x);
|
||||
blockCount.y = MAX(prtctd->_formatSize.minBlocksX, blockCount.y);
|
||||
blockCount.y = MAX(prtctd->_formatSize.minBlocksY, blockCount.y);
|
||||
|
||||
blockSizeInBytes = prtctd->_formatSize.blockSizeInBits / 8;
|
||||
|
||||
|
@ -726,8 +694,10 @@ ktxTexture_layerSize(ktxTexture* This, ktx_uint32_t level,
|
|||
ktx_size_t imageSize, layerSize;
|
||||
|
||||
assert (This != NULL);
|
||||
assert (prtctd->_formatSize.blockDepth != 0);
|
||||
|
||||
blockCountZ = MAX(1, (This->baseDepth / prtctd->_formatSize.blockDepth) >> level);
|
||||
blockCountZ = ((This->baseDepth >> level) + prtctd->_formatSize.blockDepth - 1) / prtctd->_formatSize.blockDepth;
|
||||
blockCountZ = MAX(1, blockCountZ);
|
||||
imageSize = ktxTexture_calcImageSize(This, level, fv);
|
||||
layerSize = imageSize * blockCountZ;
|
||||
if (fv == KTX_FORMAT_VERSION_ONE && KTX_GL_UNPACK_ALIGNMENT != 4) {
|
||||
|
|
|
@ -458,6 +458,9 @@ ktxTexture1_constructFromStdioStream(ktxTexture1* This, FILE* stdioStream,
|
|||
* @memberof ktxTexture1 @private
|
||||
* @brief Construct a ktxTexture1 from a named KTX file.
|
||||
*
|
||||
* The file name must be encoded in utf-8. On Windows convert unicode names
|
||||
* to utf-8 with @c WideCharToMultiByte(CP_UTF8, ...) before calling.
|
||||
*
|
||||
* See ktxTextureInt_constructFromStream for details.
|
||||
*
|
||||
* @param[in] This pointer to a ktxTextureInt-sized block of memory to
|
||||
|
@ -484,7 +487,7 @@ ktxTexture1_constructFromNamedFile(ktxTexture1* This,
|
|||
if (This == NULL || filename == NULL)
|
||||
return KTX_INVALID_VALUE;
|
||||
|
||||
file = fopen(filename, "rb");
|
||||
file = ktxFOpenUTF8(filename, "rb");
|
||||
if (!file)
|
||||
return KTX_FILE_OPEN_FAILED;
|
||||
|
||||
|
@ -614,7 +617,7 @@ ktxTexture1_Create(ktxTextureCreateInfo* createInfo,
|
|||
* @~English
|
||||
* @brief Create a ktxTexture1 from a stdio stream reading from a KTX source.
|
||||
*
|
||||
* The address of a newly created ktxTexture1 reflecting the contents of the
|
||||
* The address of a newly created texture reflecting the contents of the
|
||||
* stdio stream is written to the location pointed at by @p newTex.
|
||||
*
|
||||
* The create flag KTX_TEXTURE_CREATE_LOAD_IMAGE_DATA_BIT should not be set,
|
||||
|
@ -673,14 +676,17 @@ ktxTexture1_CreateFromStdioStream(FILE* stdioStream,
|
|||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
/**
|
||||
* @memberof ktxTexture1
|
||||
* @~English
|
||||
* @brief Create a ktxTexture1 from a named KTX file.
|
||||
*
|
||||
* The address of a newly created ktxTexture1 reflecting the contents of the
|
||||
* The address of a newly created texture reflecting the contents of the
|
||||
* file is written to the location pointed at by @p newTex.
|
||||
*
|
||||
* The file name must be encoded in utf-8. On Windows convert unicode names
|
||||
* to utf-8 with @c WideCharToMultiByte(CP_UTF8, ...) before calling.
|
||||
*
|
||||
* The create flag KTX_TEXTURE_CREATE_LOAD_IMAGE_DATA_BIT should not be set,
|
||||
* if the ktxTexture1 is ultimately to be uploaded to OpenGL or Vulkan. This
|
||||
* will minimize memory usage by allowing, for example, loading the images
|
||||
|
@ -700,7 +706,7 @@ ktxTexture1_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 ktxTexture1_CreateFromStdioStream().
|
||||
*/
|
||||
KTX_error_code
|
||||
ktxTexture1_CreateFromNamedFile(const char* const filename,
|
||||
|
@ -731,7 +737,7 @@ ktxTexture1_CreateFromNamedFile(const char* const filename,
|
|||
* @~English
|
||||
* @brief Create a ktxTexture1 from KTX-formatted data in memory.
|
||||
*
|
||||
* The address of a newly created ktxTexture1 reflecting the contents of the
|
||||
* The address of a newly created texture reflecting the contents of the
|
||||
* serialized KTX data is written to the location pointed at by @p newTex.
|
||||
*
|
||||
* The create flag KTX_TEXTURE_CREATE_LOAD_IMAGE_DATA_BIT should not be set,
|
||||
|
@ -753,7 +759,7 @@ ktxTexture1_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 ktxTexture1_CreateFromStdioStream().
|
||||
*/
|
||||
KTX_error_code
|
||||
ktxTexture1_CreateFromMemory(const ktx_uint8_t* bytes, ktx_size_t size,
|
||||
|
@ -784,7 +790,7 @@ ktxTexture1_CreateFromMemory(const ktx_uint8_t* bytes, ktx_size_t size,
|
|||
* @~English
|
||||
* @brief Create a ktxTexture1 from KTX-formatted data from a `ktxStream`.
|
||||
*
|
||||
* The address of a newly created ktxTexture1 reflecting the contents of the
|
||||
* The address of a newly created texture reflecting the contents of the
|
||||
* serialized KTX data is written to the location pointed at by @p newTex.
|
||||
*
|
||||
* The create flag KTX_TEXTURE_CREATE_LOAD_IMAGE_DATA_BIT should not be set,
|
||||
|
@ -796,19 +802,17 @@ ktxTexture1_CreateFromMemory(const ktx_uint8_t* bytes, ktx_size_t size,
|
|||
* provided solely to enable implementation of the @e libktx v1 API on top of
|
||||
* ktxTexture1.
|
||||
*
|
||||
* @param[in] stream pointer to the stream to read KTX data from.
|
||||
* @param[in] pStream pointer to the stream to read KTX data from.
|
||||
* @param[in] createFlags bitmask requesting specific actions during creation.
|
||||
* @param[in,out] newTex pointer to a location in which store the address of
|
||||
* the newly created texture.
|
||||
*
|
||||
* @return KTX_SUCCESS on success, other KTX_* enum values on error.
|
||||
*
|
||||
* @exception KTX_INVALID_VALUE Either @p bytes is NULL or @p size is 0.
|
||||
*
|
||||
* For other exceptions, see ktxTexture_CreateFromStdioStream().
|
||||
* For exceptions, see ktxTexture1_CreateFromStdioStream().
|
||||
*/
|
||||
KTX_error_code
|
||||
ktxTexture1_CreateFromStream(ktxStream* stream,
|
||||
ktxTexture1_CreateFromStream(ktxStream* pStream,
|
||||
ktxTextureCreateFlags createFlags,
|
||||
ktxTexture1** newTex)
|
||||
{
|
||||
|
@ -820,7 +824,7 @@ ktxTexture1_CreateFromStream(ktxStream* stream,
|
|||
if (tex == NULL)
|
||||
return KTX_OUT_OF_MEMORY;
|
||||
|
||||
result = ktxTexture1_constructFromStream(tex, stream, createFlags);
|
||||
result = ktxTexture1_constructFromStream(tex, pStream, createFlags);
|
||||
if (result == KTX_SUCCESS)
|
||||
*newTex = (ktxTexture1*)tex;
|
||||
else {
|
||||
|
@ -1044,9 +1048,9 @@ ktxTexture1_glTypeSize(ktxTexture1* This)
|
|||
* @~English
|
||||
* @brief Iterate over the mip levels in a ktxTexture1 object.
|
||||
*
|
||||
* This is almost identical to ktxTexture_IterateLevelFaces(). The difference is
|
||||
* that the blocks of image data for non-array cube maps include all faces of
|
||||
* a mip level.
|
||||
* This is almost identical to @ref ktxTexture::ktxTexture_IterateLevelFaces
|
||||
* "ktxTexture_IterateLevelFaces". The difference is that the blocks of image
|
||||
* data for non-array cube maps include all faces of a mip level.
|
||||
*
|
||||
* This function works even if @p This->pData == 0 so it can be used to
|
||||
* obtain offsets and sizes for each level by callers who have loaded the data
|
||||
|
@ -1114,11 +1118,12 @@ ktxTexture1_IterateLevels(ktxTexture1* This, PFNKTXITERCB iterCb, void* userdata
|
|||
* @brief Iterate over the images in a ktxTexture1 object while loading the
|
||||
* image data.
|
||||
*
|
||||
* This operates similarly to ktxTexture_IterateLevelFaces() except that it
|
||||
* loads the images from the ktxTexture1's source to a temporary buffer
|
||||
* while iterating. The callback function must copy the image data if it
|
||||
* wishes to preserve it as the temporary buffer is reused for each level and
|
||||
* is freed when this function exits.
|
||||
* This operates similarly to @ref ktxTexture::ktxTexture_IterateLevelFaces
|
||||
* "ktxTexture_IterateLevelFaces" except that it loads the images from the
|
||||
* ktxTexture1's source to a temporary buffer while iterating. The callback
|
||||
* function must copy the image data if it wishes to preserve it as the
|
||||
* temporary buffer is reused for each level and is freed when this function
|
||||
* exits.
|
||||
*
|
||||
* This function is helpful for reducing memory usage when uploading the data
|
||||
* to a graphics API.
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
#include <zstd.h>
|
||||
#include <zstd_errors.h>
|
||||
#include <KHR/khr_df.h>
|
||||
|
@ -293,6 +294,10 @@ ktxFormatSize_initFromDfd(ktxFormatSize* This, ktx_uint32_t* pDfd)
|
|||
return false;
|
||||
if (result & i_PACKED_FORMAT_BIT)
|
||||
This->flags |= KTX_FORMAT_SIZE_PACKED_BIT;
|
||||
if (result & i_COMPRESSED_FORMAT_BIT)
|
||||
This->flags |= KTX_FORMAT_SIZE_COMPRESSED_BIT;
|
||||
if (result & i_YUVSDA_FORMAT_BIT)
|
||||
This->flags |= KTX_FORMAT_SIZE_YUVSDA_BIT;
|
||||
}
|
||||
}
|
||||
if (This->blockSizeInBits == 0) {
|
||||
|
@ -325,20 +330,7 @@ ktxFormatSize_initFromDfd(ktxFormatSize* This, ktx_uint32_t* pDfd)
|
|||
static uint32_t*
|
||||
ktxVk2dfd(ktx_uint32_t vkFormat)
|
||||
{
|
||||
switch(vkFormat) {
|
||||
case VK_FORMAT_D16_UNORM_S8_UINT:
|
||||
// 2 16-bit words. D16 in the first. S8 in the 8 LSBs of the second.
|
||||
return createDFDDepthStencil(16, 8, 4);
|
||||
case VK_FORMAT_D24_UNORM_S8_UINT:
|
||||
// 1 32-bit word. D24 in the MSBs. S8 in the LSBs.
|
||||
return createDFDDepthStencil(24, 8, 4);
|
||||
case VK_FORMAT_D32_SFLOAT_S8_UINT:
|
||||
// 2 32-bit words. D32 float in the first word. S8 in LSBs of the
|
||||
// second.
|
||||
return createDFDDepthStencil(32, 8, 8);
|
||||
default:
|
||||
return vk2dfd(vkFormat);
|
||||
}
|
||||
return vk2dfd(vkFormat);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -419,7 +411,7 @@ ktxTexture2_construct(ktxTexture2* This, ktxTextureCreateInfo* createInfo,
|
|||
if (!This->pDfd)
|
||||
return KTX_OUT_OF_MEMORY;
|
||||
memcpy(This->pDfd, createInfo->pDfd, *createInfo->pDfd);
|
||||
if (ktxFormatSize_initFromDfd(&formatSize, This->pDfd)) {
|
||||
if (!ktxFormatSize_initFromDfd(&formatSize, This->pDfd)) {
|
||||
result = KTX_UNSUPPORTED_TEXTURE_TYPE;
|
||||
goto cleanup;
|
||||
}
|
||||
|
@ -437,15 +429,26 @@ ktxTexture2_construct(ktxTexture2* This, ktxTextureCreateInfo* createInfo,
|
|||
|
||||
// Ideally we'd set all these things in ktxFormatSize_initFromDfd
|
||||
// but This->_protected is not allocated until ktxTexture_construct;
|
||||
if (This->isCompressed)
|
||||
if (This->isCompressed && (formatSize.flags & KTX_FORMAT_SIZE_YUVSDA_BIT) == 0) {
|
||||
This->_protected->_typeSize = 1;
|
||||
else if (formatSize.flags & KTX_FORMAT_SIZE_PACKED_BIT)
|
||||
This->_protected->_typeSize = formatSize.blockSizeInBits / 8;
|
||||
else if (formatSize.flags & (KTX_FORMAT_SIZE_DEPTH_BIT | KTX_FORMAT_SIZE_STENCIL_BIT)) {
|
||||
if (createInfo->vkFormat == VK_FORMAT_D16_UNORM_S8_UINT)
|
||||
} else if (formatSize.flags & (KTX_FORMAT_SIZE_DEPTH_BIT | KTX_FORMAT_SIZE_STENCIL_BIT)) {
|
||||
switch (createInfo->vkFormat) {
|
||||
case VK_FORMAT_S8_UINT:
|
||||
This->_protected->_typeSize = 1;
|
||||
break;
|
||||
case VK_FORMAT_D16_UNORM: // [[fallthrough]];
|
||||
case VK_FORMAT_D16_UNORM_S8_UINT:
|
||||
This->_protected->_typeSize = 2;
|
||||
else
|
||||
break;
|
||||
case VK_FORMAT_X8_D24_UNORM_PACK32: // [[fallthrough]];
|
||||
case VK_FORMAT_D24_UNORM_S8_UINT: // [[fallthrough]];
|
||||
case VK_FORMAT_D32_SFLOAT: // [[fallthrough]];
|
||||
case VK_FORMAT_D32_SFLOAT_S8_UINT:
|
||||
This->_protected->_typeSize = 4;
|
||||
break;
|
||||
}
|
||||
} else if (formatSize.flags & KTX_FORMAT_SIZE_PACKED_BIT) {
|
||||
This->_protected->_typeSize = formatSize.blockSizeInBits / 8;
|
||||
} else {
|
||||
// Unpacked and uncompressed
|
||||
uint32_t numComponents;
|
||||
|
@ -503,7 +506,7 @@ cleanup:
|
|||
*
|
||||
* @exception KTX_OUT_OF_MEMORY Not enough memory for the texture data.
|
||||
*/
|
||||
static KTX_error_code
|
||||
KTX_error_code
|
||||
ktxTexture2_constructCopy(ktxTexture2* This, ktxTexture2* orig)
|
||||
{
|
||||
KTX_error_code result;
|
||||
|
@ -648,6 +651,7 @@ ktxTexture2_constructFromStreamAndHeader(ktxTexture2* This, ktxStream* pStream,
|
|||
KTX_error_code result;
|
||||
KTX_supplemental_info suppInfo;
|
||||
ktxStream* stream;
|
||||
struct BDFD* pBDFD;
|
||||
ktx_size_t levelIndexSize;
|
||||
|
||||
assert(pHeader != NULL && pStream != NULL);
|
||||
|
@ -721,9 +725,21 @@ ktxTexture2_constructFromStreamAndHeader(ktxTexture2* This, ktxStream* pStream,
|
|||
for (ktx_uint32_t level = 0; level < This->numLevels; level++) {
|
||||
private->_levelIndex[level].byteOffset
|
||||
-= private->_firstLevelFileOffset;
|
||||
if (This->supercompressionScheme == KTX_SS_NONE &&
|
||||
private->_levelIndex[level].byteLength != private->_levelIndex[level].uncompressedByteLength) {
|
||||
// For non-supercompressed files the levels must have matching byte lengths
|
||||
result = KTX_FILE_DATA_ERROR;
|
||||
}
|
||||
}
|
||||
if (result != KTX_SUCCESS)
|
||||
goto cleanup;
|
||||
|
||||
// Read DFD
|
||||
if (pHeader->dataFormatDescriptor.byteOffset == 0 || pHeader->dataFormatDescriptor.byteLength < 16) {
|
||||
// Missing or too small DFD
|
||||
result = KTX_FILE_DATA_ERROR;
|
||||
goto cleanup;
|
||||
}
|
||||
This->pDfd =
|
||||
(ktx_uint32_t*)malloc(pHeader->dataFormatDescriptor.byteLength);
|
||||
if (!This->pDfd) {
|
||||
|
@ -735,19 +751,87 @@ ktxTexture2_constructFromStreamAndHeader(ktxTexture2* This, ktxStream* pStream,
|
|||
if (result != KTX_SUCCESS)
|
||||
goto cleanup;
|
||||
|
||||
if (pHeader->dataFormatDescriptor.byteLength != This->pDfd[0]) {
|
||||
// DFD byteLength does not match dfdTotalSize
|
||||
result = KTX_FILE_DATA_ERROR;
|
||||
goto cleanup;
|
||||
}
|
||||
pBDFD = (struct BDFD*)(This->pDfd + 1);
|
||||
if (pBDFD->descriptorBlockSize < 24 || (pBDFD->descriptorBlockSize - 24) % 16 != 0) {
|
||||
// BDFD has invalid size
|
||||
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 (!ktxFormatSize_initFromDfd(&This->_protected->_formatSize, This->pDfd)) {
|
||||
result = KTX_UNSUPPORTED_TEXTURE_TYPE;
|
||||
goto cleanup;
|
||||
}
|
||||
This->isCompressed = (This->_protected->_formatSize.flags & KTX_FORMAT_SIZE_COMPRESSED_BIT);
|
||||
|
||||
if (This->supercompressionScheme == KTX_SS_BASIS_LZ
|
||||
&& KHR_DFDVAL(This->pDfd + 1, MODEL) != KHR_DF_MODEL_ETC1S)
|
||||
{
|
||||
if (This->supercompressionScheme == KTX_SS_BASIS_LZ && pBDFD->model != KHR_DF_MODEL_ETC1S) {
|
||||
result = KTX_FILE_DATA_ERROR;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
// Check compatibility with the KHR_texture_basisu glTF extension, if needed.
|
||||
if (createFlags & KTX_TEXTURE_CREATE_CHECK_GLTF_BASISU_BIT) {
|
||||
uint32_t max_dim = MAX(MAX(pHeader->pixelWidth, pHeader->pixelHeight), pHeader->pixelDepth);
|
||||
uint32_t full_mip_pyramid_level_count = 1 + (uint32_t)log2(max_dim);
|
||||
if (pHeader->levelCount != 1 && pHeader->levelCount != full_mip_pyramid_level_count) {
|
||||
// KHR_texture_basisu requires full mip pyramid or single mip level
|
||||
result = KTX_FILE_DATA_ERROR;
|
||||
goto cleanup;
|
||||
}
|
||||
if (This->numDimensions != 2 || This->isArray || This->isCubemap) {
|
||||
// KHR_texture_basisu requires 2D textures.
|
||||
result = KTX_FILE_DATA_ERROR;
|
||||
goto cleanup;
|
||||
}
|
||||
if ((This->baseWidth % 4) != 0 || (This->baseHeight % 4) != 0) {
|
||||
// KHR_texture_basisu requires width and height to be a multiple of 4.
|
||||
result = KTX_FILE_DATA_ERROR;
|
||||
goto cleanup;
|
||||
}
|
||||
if (pBDFD->model != KHR_DF_MODEL_ETC1S && pBDFD->model != KHR_DF_MODEL_UASTC) {
|
||||
// KHR_texture_basisu requires BasisLZ or UASTC
|
||||
result = KTX_FILE_DATA_ERROR;
|
||||
goto cleanup;
|
||||
}
|
||||
if (pBDFD->model == KHR_DF_MODEL_UASTC &&
|
||||
This->supercompressionScheme != KTX_SS_NONE &&
|
||||
This->supercompressionScheme != KTX_SS_ZSTD) {
|
||||
// KHR_texture_basisu only allows NONE and ZSTD supercompression for UASTC
|
||||
result = KTX_FILE_DATA_ERROR;
|
||||
goto cleanup;
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t sampleCount = KHR_DFDSAMPLECOUNT(This->pDfd + 1);
|
||||
if (sampleCount == 0) {
|
||||
// Invalid sample count
|
||||
result = KTX_FILE_DATA_ERROR;
|
||||
goto cleanup;
|
||||
}
|
||||
if (pBDFD->model == KHR_DF_MODEL_ETC1S || pBDFD->model == KHR_DF_MODEL_UASTC) {
|
||||
if (sampleCount < 1 || sampleCount > 2 || (sampleCount == 2 && pBDFD->model == KHR_DF_MODEL_UASTC)) {
|
||||
// Invalid sample count
|
||||
result = KTX_FILE_DATA_ERROR;
|
||||
goto cleanup;
|
||||
}
|
||||
if (pBDFD->texelBlockDimension0 != 3 || pBDFD->texelBlockDimension1 != 3 ||
|
||||
pBDFD->texelBlockDimension2 != 0 || pBDFD->texelBlockDimension3 != 0) {
|
||||
// Texel block dimension must be 4x4x1x1 (offset by one)
|
||||
result = KTX_FILE_DATA_ERROR;
|
||||
goto cleanup;
|
||||
}
|
||||
}
|
||||
|
||||
This->_private->_requiredLevelAlignment
|
||||
= ktxTexture2_calcRequiredLevelAlignment(This);
|
||||
|
||||
|
@ -755,6 +839,12 @@ ktxTexture2_constructFromStreamAndHeader(ktxTexture2* This, ktxStream* pStream,
|
|||
ktxHashList_Construct(&This->kvDataHead);
|
||||
// Load KVData.
|
||||
if (pHeader->keyValueData.byteLength > 0) {
|
||||
uint32_t expectedOffset = pHeader->dataFormatDescriptor.byteOffset + pHeader->dataFormatDescriptor.byteLength;
|
||||
expectedOffset = (expectedOffset + 3) & ~0x3; // 4 byte aligned
|
||||
if (pHeader->keyValueData.byteOffset != expectedOffset) {
|
||||
result = KTX_FILE_DATA_ERROR;
|
||||
goto cleanup;
|
||||
}
|
||||
if (!(createFlags & KTX_TEXTURE_CREATE_SKIP_KVDATA_BIT)) {
|
||||
ktx_uint32_t kvdLen = pHeader->keyValueData.byteLength;
|
||||
ktx_uint8_t* pKvd;
|
||||
|
@ -850,9 +940,30 @@ ktxTexture2_constructFromStreamAndHeader(ktxTexture2* This, ktxStream* pStream,
|
|||
} else {
|
||||
stream->skip(stream, pHeader->keyValueData.byteLength);
|
||||
}
|
||||
} else if (pHeader->keyValueData.byteOffset != 0) {
|
||||
// Non-zero KVD byteOffset with zero byteLength
|
||||
result = KTX_FILE_DATA_ERROR;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (pHeader->supercompressionGlobalData.byteLength > 0) {
|
||||
switch (This->supercompressionScheme) {
|
||||
case KTX_SS_BASIS_LZ:
|
||||
break;
|
||||
case KTX_SS_NONE:
|
||||
case KTX_SS_ZSTD:
|
||||
case KTX_SS_ZLIB:
|
||||
// In these cases SGD is not allowed
|
||||
result = KTX_FILE_DATA_ERROR;
|
||||
break;
|
||||
default:
|
||||
// We don't support other supercompression schemes
|
||||
result = KTX_UNSUPPORTED_FEATURE;
|
||||
break;
|
||||
}
|
||||
if (result != KTX_SUCCESS)
|
||||
goto cleanup;
|
||||
|
||||
// There could be padding here so seek to the next item.
|
||||
(void)stream->setpos(stream,
|
||||
pHeader->supercompressionGlobalData.byteOffset);
|
||||
|
@ -871,6 +982,14 @@ ktxTexture2_constructFromStreamAndHeader(ktxTexture2* This, ktxStream* pStream,
|
|||
|
||||
if (result != KTX_SUCCESS)
|
||||
goto cleanup;
|
||||
} else if (pHeader->supercompressionGlobalData.byteOffset != 0) {
|
||||
// Non-zero SGD byteOffset with zero byteLength
|
||||
result = KTX_FILE_DATA_ERROR;
|
||||
goto cleanup;
|
||||
} else if (This->supercompressionScheme == KTX_SS_BASIS_LZ) {
|
||||
// SGD is required for BasisLZ
|
||||
result = KTX_FILE_DATA_ERROR;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
// Calculate size of the image data. Level 0 is the last level in the data.
|
||||
|
@ -982,6 +1101,9 @@ ktxTexture2_constructFromStdioStream(ktxTexture2* This, FILE* stdioStream,
|
|||
* @~English
|
||||
* @brief Construct a ktxTexture from a named KTX file.
|
||||
*
|
||||
* The file name must be encoded in utf-8. On Windows convert unicode names
|
||||
* to utf-8 with @c WideCharToMultiByte(CP_UTF8, ...) before calling.
|
||||
*
|
||||
* See ktxTextureInt_constructFromStream for details.
|
||||
*
|
||||
* @param[in] This pointer to a ktxTextureInt-sized block of memory to
|
||||
|
@ -1008,7 +1130,7 @@ ktxTexture2_constructFromNamedFile(ktxTexture2* This,
|
|||
if (This == NULL || filename == NULL)
|
||||
return KTX_INVALID_VALUE;
|
||||
|
||||
file = fopen(filename, "rb");
|
||||
file = ktxFOpenUTF8(filename, "rb");
|
||||
if (!file)
|
||||
return KTX_FILE_OPEN_FAILED;
|
||||
|
||||
|
@ -1259,6 +1381,9 @@ ktxTexture2_CreateFromStdioStream(FILE* stdioStream,
|
|||
* The address of a newly created ktxTexture2 reflecting the contents of the
|
||||
* file is written to the location pointed at by @p newTex.
|
||||
*
|
||||
* The file name must be encoded in utf-8. On Windows convert unicode names
|
||||
* to utf-8 with @c WideCharToMultiByte(CP_UTF8, ...) before calling.
|
||||
*
|
||||
* The create flag KTX_TEXTURE_CREATE_LOAD_IMAGE_DATA_BIT should not be set,
|
||||
* if the ktxTexture is ultimately to be uploaded to OpenGL or Vulkan. This
|
||||
* will minimize memory usage by allowing, for example, loading the images
|
||||
|
@ -1581,7 +1706,7 @@ ktxTexture2_calcPostInflationLevelAlignment(ktxTexture2* This)
|
|||
|
||||
// Should actually work for none supercompressed but don't want to
|
||||
// encourage use of it.
|
||||
assert(This->supercompressionScheme >= KTX_SS_ZSTD);
|
||||
assert(This->supercompressionScheme != KTX_SS_NONE && This->supercompressionScheme != KTX_SS_BASIS_LZ);
|
||||
|
||||
if (This->vkFormat != VK_FORMAT_UNDEFINED)
|
||||
alignment = lcm4(This->_protected->_formatSize.blockSizeInBits / 8);
|
||||
|
@ -1834,15 +1959,17 @@ ktxTexture2_NeedsTranscoding(ktxTexture2* This)
|
|||
/**
|
||||
* @memberof ktxTexture2
|
||||
* @~English
|
||||
* @brief Return the total size in bytes of the uncompressed data of a ktxTexture2.
|
||||
* @brief Return the total size in bytes of the uncompressed data of a
|
||||
* ktxTexture2.
|
||||
*
|
||||
* If supercompressionScheme == KTX_SS_NONE or
|
||||
* KTX_SS_BASIS_LZ, returns the value of @c This->dataSize
|
||||
* else if supercompressionScheme == KTX_SS_ZSTD, it returns the
|
||||
* sum of the uncompressed sizes of each mip level plus space for the level padding. With no
|
||||
* supercompression the data size and uncompressed data size are the same. For Basis
|
||||
* supercompression the uncompressed size cannot be known until the data is transcoded
|
||||
* so the compressed size is returned.
|
||||
* If supercompressionScheme == @c KTX_SS_NONE or
|
||||
* @c KTX_SS_BASIS_LZ, returns the value of @c This->dataSize
|
||||
* else if supercompressionScheme == @c KTX_SS_ZSTD or @c KTX_SS_ZLIB, it
|
||||
* returns the sum of the uncompressed sizes of each mip level plus space for
|
||||
* the level padding. With no supercompression the data size and uncompressed
|
||||
* data size are the same. For Basis supercompression the uncompressed size
|
||||
* cannot be known until the data is transcoded so the compressed size is
|
||||
* returned.
|
||||
*
|
||||
* @param[in] This pointer to the ktxTexture1 object of interest.
|
||||
*/
|
||||
|
@ -1854,6 +1981,7 @@ ktxTexture2_GetDataSizeUncompressed(ktxTexture2* This)
|
|||
case KTX_SS_NONE:
|
||||
return This->dataSize;
|
||||
case KTX_SS_ZSTD:
|
||||
case KTX_SS_ZLIB:
|
||||
{
|
||||
ktx_size_t uncompressedSize = 0;
|
||||
ktx_uint32_t uncompressedLevelAlignment;
|
||||
|
@ -1984,7 +2112,7 @@ ktxTexture2_IterateLevels(ktxTexture2* This, PFNKTXITERCB iterCb, void* userdata
|
|||
*
|
||||
* This operates similarly to ktxTexture_IterateLevelFaces() except that it
|
||||
* loads the images from the ktxTexture2's source to a temporary buffer
|
||||
* while iterating. If supercompressionScheme == KTX_SS_ZSTD,
|
||||
* while iterating. If supercompressionScheme == KTX_SS_ZSTD or KTX_SS_ZLIB,
|
||||
* it will inflate the data before passing it to the callback. The callback function
|
||||
* must copy the image data if it wishes to preserve it as the temporary buffer
|
||||
* is reused for each level and is freed when this function exits.
|
||||
|
@ -1992,8 +2120,8 @@ ktxTexture2_IterateLevels(ktxTexture2* This, PFNKTXITERCB iterCb, void* userdata
|
|||
* This function is helpful for reducing memory usage when uploading the data
|
||||
* to a graphics API.
|
||||
*
|
||||
* Intended for use only when supercompressionScheme == SUPERCOMPRESSION_NONE
|
||||
* or SUPERCOMPRESSION_ZSTD. As there is no access to the ktxTexture's data on
|
||||
* Intended for use only when supercompressionScheme == KTX_SS_NONE,
|
||||
* KTX_SS_ZSTD or KTX_SS_ZLIB. As there is no access to the ktxTexture's data on
|
||||
* conclusion of this function, destroying the texture on completion is recommended.
|
||||
*
|
||||
* @param[in] This pointer to the ktxTexture2 object of interest.
|
||||
|
@ -2013,8 +2141,9 @@ ktxTexture2_IterateLevels(ktxTexture2* This, PFNKTXITERCB iterCb, void* userdata
|
|||
* this ktxTexture2's images have already
|
||||
* been loaded.
|
||||
* @exception KTX_INVALID_OPERATION
|
||||
* supercompressionScheme != SUPERCOMPRESSION_NONE.
|
||||
* and supercompressionScheme != SUPERCOMPRESSION_ZSTD.
|
||||
* supercompressionScheme != KTX_SS_NONE,
|
||||
* supercompressionScheme != KTX_SS_ZSTD, and
|
||||
* supercompressionScheme != KTX_SS_ZLIB.
|
||||
* @exception KTX_INVALID_VALUE @p This is @c NULL or @p iterCb is @c NULL.
|
||||
* @exception KTX_OUT_OF_MEMORY not enough memory to allocate a block to
|
||||
* hold the base level image.
|
||||
|
@ -2040,7 +2169,8 @@ ktxTexture2_IterateLoadLevelFaces(ktxTexture2* This, PFNKTXITERCB iterCb,
|
|||
return KTX_INVALID_OPERATION;
|
||||
|
||||
if (This->supercompressionScheme != KTX_SS_NONE &&
|
||||
This->supercompressionScheme != KTX_SS_ZSTD)
|
||||
This->supercompressionScheme != KTX_SS_ZSTD &&
|
||||
This->supercompressionScheme != KTX_SS_ZLIB)
|
||||
return KTX_INVALID_OPERATION;
|
||||
|
||||
if (iterCb == NULL)
|
||||
|
@ -2057,14 +2187,16 @@ ktxTexture2_IterateLoadLevelFaces(ktxTexture2* This, PFNKTXITERCB iterCb,
|
|||
dataBuf = malloc(dataSize);
|
||||
if (!dataBuf)
|
||||
return KTX_OUT_OF_MEMORY;
|
||||
if (This->supercompressionScheme == KTX_SS_ZSTD) {
|
||||
if (This->supercompressionScheme == KTX_SS_ZSTD || This->supercompressionScheme == KTX_SS_ZLIB) {
|
||||
uncompressedDataSize = levelIndex[0].uncompressedByteLength;
|
||||
uncompressedDataBuf = malloc(uncompressedDataSize);
|
||||
if (!uncompressedDataBuf) {
|
||||
result = KTX_OUT_OF_MEMORY;
|
||||
goto cleanup;
|
||||
}
|
||||
dctx = ZSTD_createDCtx();
|
||||
if (This->supercompressionScheme == KTX_SS_ZSTD) {
|
||||
dctx = ZSTD_createDCtx();
|
||||
}
|
||||
pData = uncompressedDataBuf;
|
||||
} else {
|
||||
pData = dataBuf;
|
||||
|
@ -2107,21 +2239,34 @@ ktxTexture2_IterateLoadLevelFaces(ktxTexture2* This, PFNKTXITERCB iterCb,
|
|||
ZSTD_ErrorCode error = ZSTD_getErrorCode(levelSize);
|
||||
switch(error) {
|
||||
case ZSTD_error_dstSize_tooSmall:
|
||||
return KTX_INVALID_VALUE; // inflatedDataCapacity too small.
|
||||
return KTX_DECOMPRESS_LENGTH_ERROR; // inflatedDataCapacity too small.
|
||||
case ZSTD_error_checksum_wrong:
|
||||
return KTX_DECOMPRESS_CHECKSUM_ERROR;
|
||||
case ZSTD_error_memory_allocation:
|
||||
return KTX_OUT_OF_MEMORY;
|
||||
default:
|
||||
return KTX_FILE_DATA_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
// We don't fix up the texture's dataSize, levelIndex or
|
||||
// _requiredAlignment because after this function completes there
|
||||
// is no way to get at the texture's data.
|
||||
//nindex[level].byteOffset = levelOffset;
|
||||
//nindex[level].uncompressedByteLength = nindex[level].byteLength =
|
||||
//levelByteLength;
|
||||
} else if (This->supercompressionScheme == KTX_SS_ZLIB) {
|
||||
result = ktxUncompressZLIBInt(uncompressedDataBuf,
|
||||
&uncompressedDataSize,
|
||||
dataBuf,
|
||||
levelSize);
|
||||
if (result != KTX_SUCCESS)
|
||||
return result;
|
||||
}
|
||||
|
||||
if (levelIndex[level].uncompressedByteLength != levelSize)
|
||||
return KTX_DECOMPRESS_LENGTH_ERROR;
|
||||
|
||||
#if IS_BIG_ENDIAN
|
||||
switch (prtctd->_typeSize) {
|
||||
case 2:
|
||||
|
@ -2188,16 +2333,23 @@ KTX_error_code
|
|||
ktxTexture2_inflateZstdInt(ktxTexture2* This, ktx_uint8_t* pDeflatedData,
|
||||
ktx_uint8_t* pInflatedData,
|
||||
ktx_size_t inflatedDataCapacity);
|
||||
|
||||
KTX_error_code
|
||||
ktxTexture2_inflateZLIBInt(ktxTexture2* This, ktx_uint8_t* pDeflatedData,
|
||||
ktx_uint8_t* pInflatedData,
|
||||
ktx_size_t inflatedDataCapacity);
|
||||
|
||||
/**
|
||||
* @memberof ktxTexture2
|
||||
* @~English
|
||||
* @brief Load all the image data from the ktxTexture2's source.
|
||||
*
|
||||
* The data will be inflated if supercompressionScheme == SUPERCOMPRESSION_ZSTD.
|
||||
* 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. See ktxTexture2_GetDataSizeUncompressed().
|
||||
* 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.
|
||||
|
@ -2248,7 +2400,7 @@ ktxTexture2_LoadImageData(ktxTexture2* This,
|
|||
pDest = pBuffer;
|
||||
}
|
||||
|
||||
if (This->supercompressionScheme == KTX_SS_ZSTD) {
|
||||
if (This->supercompressionScheme == KTX_SS_ZSTD || This->supercompressionScheme == KTX_SS_ZLIB) {
|
||||
// Create buffer to hold deflated data.
|
||||
pDeflatedData = malloc(This->dataSize);
|
||||
if (pDeflatedData == NULL)
|
||||
|
@ -2271,10 +2423,15 @@ ktxTexture2_LoadImageData(ktxTexture2* This,
|
|||
if (result != KTX_SUCCESS)
|
||||
return result;
|
||||
|
||||
if (This->supercompressionScheme == KTX_SS_ZSTD) {
|
||||
if (This->supercompressionScheme == KTX_SS_ZSTD || This->supercompressionScheme == KTX_SS_ZLIB) {
|
||||
assert(pDeflatedData != NULL);
|
||||
result = ktxTexture2_inflateZstdInt(This, pDeflatedData, pDest,
|
||||
inflatedDataCapacity);
|
||||
if (This->supercompressionScheme == KTX_SS_ZSTD) {
|
||||
result = ktxTexture2_inflateZstdInt(This, pDeflatedData, pDest,
|
||||
inflatedDataCapacity);
|
||||
} else if (This->supercompressionScheme == KTX_SS_ZLIB) {
|
||||
result = ktxTexture2_inflateZLIBInt(This, pDeflatedData, pDest,
|
||||
inflatedDataCapacity);
|
||||
}
|
||||
free(pDeflatedData);
|
||||
if (result != KTX_SUCCESS) {
|
||||
if (pBuffer == NULL) {
|
||||
|
@ -2388,13 +2545,19 @@ ktxTexture2_inflateZstdInt(ktxTexture2* This, ktx_uint8_t* pDeflatedData,
|
|||
ZSTD_ErrorCode error = ZSTD_getErrorCode(levelByteLength);
|
||||
switch(error) {
|
||||
case ZSTD_error_dstSize_tooSmall:
|
||||
return KTX_INVALID_VALUE; // inflatedDataCapacity too small.
|
||||
return KTX_DECOMPRESS_LENGTH_ERROR; // inflatedDataCapacity too small.
|
||||
case ZSTD_error_checksum_wrong:
|
||||
return KTX_DECOMPRESS_CHECKSUM_ERROR;
|
||||
case ZSTD_error_memory_allocation:
|
||||
return KTX_OUT_OF_MEMORY;
|
||||
default:
|
||||
return KTX_FILE_DATA_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
if (This->_private->_levelIndex[level].uncompressedByteLength != levelByteLength)
|
||||
return KTX_DECOMPRESS_LENGTH_ERROR;
|
||||
|
||||
nindex[level].byteOffset = levelOffset;
|
||||
nindex[level].uncompressedByteLength = nindex[level].byteLength =
|
||||
levelByteLength;
|
||||
|
@ -2421,6 +2584,89 @@ ktxTexture2_inflateZstdInt(ktxTexture2* This, ktx_uint8_t* pDeflatedData,
|
|||
return KTX_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* @memberof ktxTexture2 @private
|
||||
* @~English
|
||||
* @brief Inflate the data in a ktxTexture2 object using miniz (ZLIB).
|
||||
*
|
||||
* 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 ktxTexture2 object of interest.
|
||||
* @param[in] pDeflatedData pointer to a buffer containing the deflated
|
||||
* data of the entire texture.
|
||||
* @param[in,out] pInflatedData pointer to a buffer in which to write the
|
||||
* inflated data.
|
||||
* @param[in] inflatedDataCapacity capacity of the buffer pointed at by
|
||||
* @p pInflatedData.
|
||||
*/
|
||||
KTX_error_code
|
||||
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;
|
||||
ktxLevelIndexEntry* cindex = This->_private->_levelIndex;
|
||||
ktxLevelIndexEntry* nindex;
|
||||
ktx_uint32_t uncompressedLevelAlignment;
|
||||
|
||||
if (pDeflatedData == NULL)
|
||||
return KTX_INVALID_VALUE;
|
||||
|
||||
if (pInflatedData == NULL)
|
||||
return KTX_INVALID_VALUE;
|
||||
|
||||
if (This->supercompressionScheme != KTX_SS_ZLIB)
|
||||
return KTX_INVALID_OPERATION;
|
||||
|
||||
nindex = malloc(levelIndexByteLength);
|
||||
if (nindex == NULL)
|
||||
return KTX_OUT_OF_MEMORY;
|
||||
|
||||
uncompressedLevelAlignment =
|
||||
ktxTexture2_calcPostInflationLevelAlignment(This);
|
||||
|
||||
ktx_size_t inflatedByteLength = 0;
|
||||
for (int32_t level = This->numLevels - 1; level >= 0; level--) {
|
||||
size_t levelByteLength = inflatedDataCapacity;
|
||||
KTX_error_code result = ktxUncompressZLIBInt(pInflatedData + levelOffset,
|
||||
&levelByteLength,
|
||||
&pDeflatedData[cindex[level].byteOffset],
|
||||
cindex[level].byteLength);
|
||||
if (result != KTX_SUCCESS)
|
||||
return result;
|
||||
|
||||
if (This->_private->_levelIndex[level].uncompressedByteLength != levelByteLength)
|
||||
return KTX_DECOMPRESS_LENGTH_ERROR;
|
||||
|
||||
nindex[level].byteOffset = levelOffset;
|
||||
nindex[level].uncompressedByteLength = nindex[level].byteLength =
|
||||
levelByteLength;
|
||||
ktx_size_t paddedLevelByteLength
|
||||
= _KTX_PADN(uncompressedLevelAlignment, levelByteLength);
|
||||
inflatedByteLength += paddedLevelByteLength;
|
||||
levelOffset += paddedLevelByteLength;
|
||||
inflatedDataCapacity -= paddedLevelByteLength;
|
||||
}
|
||||
|
||||
// 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;
|
||||
}
|
||||
|
||||
#if !KTX_FEATURE_WRITE
|
||||
|
||||
/*
|
||||
|
|
|
@ -50,6 +50,8 @@ KTX_error_code
|
|||
ktxTexture2_LoadImageData(ktxTexture2* This,
|
||||
ktx_uint8_t* pBuffer, ktx_size_t bufSize);
|
||||
|
||||
KTX_error_code
|
||||
ktxTexture2_constructCopy(ktxTexture2* This, ktxTexture2* orig);
|
||||
KTX_error_code
|
||||
ktxTexture2_constructFromStreamAndHeader(ktxTexture2* This, ktxStream* pStream,
|
||||
KTX_header2* pHeader,
|
||||
|
|
|
@ -0,0 +1,165 @@
|
|||
|
||||
/***************************** Do not edit. *****************************
|
||||
Automatically generated from vulkan_core.h version 267 by mkvkformatfiles.
|
||||
*************************************************************************/
|
||||
|
||||
/*
|
||||
** Copyright 2015-2023 The Khronos Group Inc.
|
||||
**
|
||||
** SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#include "vkformat_enum.h"
|
||||
|
||||
bool
|
||||
isProhibitedFormat(VkFormat format)
|
||||
{
|
||||
switch (format) {
|
||||
case VK_FORMAT_R8_USCALED:
|
||||
case VK_FORMAT_R8_SSCALED:
|
||||
case VK_FORMAT_R8G8_USCALED:
|
||||
case VK_FORMAT_R8G8_SSCALED:
|
||||
case VK_FORMAT_R8G8B8_USCALED:
|
||||
case VK_FORMAT_R8G8B8_SSCALED:
|
||||
case VK_FORMAT_B8G8R8_USCALED:
|
||||
case VK_FORMAT_B8G8R8_SSCALED:
|
||||
case VK_FORMAT_R8G8B8A8_USCALED:
|
||||
case VK_FORMAT_R8G8B8A8_SSCALED:
|
||||
case VK_FORMAT_B8G8R8A8_USCALED:
|
||||
case VK_FORMAT_B8G8R8A8_SSCALED:
|
||||
case VK_FORMAT_A8B8G8R8_UNORM_PACK32:
|
||||
case VK_FORMAT_A8B8G8R8_SNORM_PACK32:
|
||||
case VK_FORMAT_A8B8G8R8_USCALED_PACK32:
|
||||
case VK_FORMAT_A8B8G8R8_SSCALED_PACK32:
|
||||
case VK_FORMAT_A8B8G8R8_UINT_PACK32:
|
||||
case VK_FORMAT_A8B8G8R8_SINT_PACK32:
|
||||
case VK_FORMAT_A8B8G8R8_SRGB_PACK32:
|
||||
case VK_FORMAT_A2R10G10B10_USCALED_PACK32:
|
||||
case VK_FORMAT_A2R10G10B10_SSCALED_PACK32:
|
||||
case VK_FORMAT_A2B10G10R10_USCALED_PACK32:
|
||||
case VK_FORMAT_A2B10G10R10_SSCALED_PACK32:
|
||||
case VK_FORMAT_R16_USCALED:
|
||||
case VK_FORMAT_R16_SSCALED:
|
||||
case VK_FORMAT_R16G16_USCALED:
|
||||
case VK_FORMAT_R16G16_SSCALED:
|
||||
case VK_FORMAT_R16G16B16_USCALED:
|
||||
case VK_FORMAT_R16G16B16_SSCALED:
|
||||
case VK_FORMAT_R16G16B16A16_USCALED:
|
||||
case VK_FORMAT_R16G16B16A16_SSCALED:
|
||||
case VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM:
|
||||
case VK_FORMAT_G8_B8R8_2PLANE_420_UNORM:
|
||||
case VK_FORMAT_G8_B8_R8_3PLANE_422_UNORM:
|
||||
case VK_FORMAT_G8_B8R8_2PLANE_422_UNORM:
|
||||
case VK_FORMAT_G8_B8_R8_3PLANE_444_UNORM:
|
||||
case VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_420_UNORM_3PACK16:
|
||||
case VK_FORMAT_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16:
|
||||
case VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_422_UNORM_3PACK16:
|
||||
case VK_FORMAT_G10X6_B10X6R10X6_2PLANE_422_UNORM_3PACK16:
|
||||
case VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_444_UNORM_3PACK16:
|
||||
case VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_420_UNORM_3PACK16:
|
||||
case VK_FORMAT_G12X4_B12X4R12X4_2PLANE_420_UNORM_3PACK16:
|
||||
case VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_422_UNORM_3PACK16:
|
||||
case VK_FORMAT_G12X4_B12X4R12X4_2PLANE_422_UNORM_3PACK16:
|
||||
case VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_444_UNORM_3PACK16:
|
||||
case VK_FORMAT_G16_B16_R16_3PLANE_420_UNORM:
|
||||
case VK_FORMAT_G16_B16R16_2PLANE_420_UNORM:
|
||||
case VK_FORMAT_G16_B16_R16_3PLANE_422_UNORM:
|
||||
case VK_FORMAT_G16_B16R16_2PLANE_422_UNORM:
|
||||
case VK_FORMAT_G16_B16_R16_3PLANE_444_UNORM:
|
||||
case VK_FORMAT_G8_B8R8_2PLANE_444_UNORM:
|
||||
case VK_FORMAT_G10X6_B10X6R10X6_2PLANE_444_UNORM_3PACK16:
|
||||
case VK_FORMAT_G12X4_B12X4R12X4_2PLANE_444_UNORM_3PACK16:
|
||||
case VK_FORMAT_G16_B16R16_2PLANE_444_UNORM:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
isValidFormat(VkFormat format)
|
||||
{
|
||||
// On MSVC VkFormat can be a signed integer
|
||||
if ((uint32_t) format <= VK_FORMAT_MAX_STANDARD_ENUM)
|
||||
return true;
|
||||
else switch(format) {
|
||||
case VK_FORMAT_G8B8G8R8_422_UNORM:
|
||||
case VK_FORMAT_B8G8R8G8_422_UNORM:
|
||||
case VK_FORMAT_R10X6_UNORM_PACK16:
|
||||
case VK_FORMAT_R10X6G10X6_UNORM_2PACK16:
|
||||
case VK_FORMAT_R10X6G10X6B10X6A10X6_UNORM_4PACK16:
|
||||
case VK_FORMAT_G10X6B10X6G10X6R10X6_422_UNORM_4PACK16:
|
||||
case VK_FORMAT_B10X6G10X6R10X6G10X6_422_UNORM_4PACK16:
|
||||
case VK_FORMAT_R12X4_UNORM_PACK16:
|
||||
case VK_FORMAT_R12X4G12X4_UNORM_2PACK16:
|
||||
case VK_FORMAT_R12X4G12X4B12X4A12X4_UNORM_4PACK16:
|
||||
case VK_FORMAT_G12X4B12X4G12X4R12X4_422_UNORM_4PACK16:
|
||||
case VK_FORMAT_B12X4G12X4R12X4G12X4_422_UNORM_4PACK16:
|
||||
case VK_FORMAT_G16B16G16R16_422_UNORM:
|
||||
case VK_FORMAT_B16G16R16G16_422_UNORM:
|
||||
case VK_FORMAT_A4R4G4B4_UNORM_PACK16:
|
||||
case VK_FORMAT_A4B4G4R4_UNORM_PACK16:
|
||||
case VK_FORMAT_ASTC_4x4_SFLOAT_BLOCK:
|
||||
case VK_FORMAT_ASTC_5x4_SFLOAT_BLOCK:
|
||||
case VK_FORMAT_ASTC_5x5_SFLOAT_BLOCK:
|
||||
case VK_FORMAT_ASTC_6x5_SFLOAT_BLOCK:
|
||||
case VK_FORMAT_ASTC_6x6_SFLOAT_BLOCK:
|
||||
case VK_FORMAT_ASTC_8x5_SFLOAT_BLOCK:
|
||||
case VK_FORMAT_ASTC_8x6_SFLOAT_BLOCK:
|
||||
case VK_FORMAT_ASTC_8x8_SFLOAT_BLOCK:
|
||||
case VK_FORMAT_ASTC_10x5_SFLOAT_BLOCK:
|
||||
case VK_FORMAT_ASTC_10x6_SFLOAT_BLOCK:
|
||||
case VK_FORMAT_ASTC_10x8_SFLOAT_BLOCK:
|
||||
case VK_FORMAT_ASTC_10x10_SFLOAT_BLOCK:
|
||||
case VK_FORMAT_ASTC_12x10_SFLOAT_BLOCK:
|
||||
case VK_FORMAT_ASTC_12x12_SFLOAT_BLOCK:
|
||||
case VK_FORMAT_PVRTC1_2BPP_UNORM_BLOCK_IMG:
|
||||
case VK_FORMAT_PVRTC1_4BPP_UNORM_BLOCK_IMG:
|
||||
case VK_FORMAT_PVRTC2_2BPP_UNORM_BLOCK_IMG:
|
||||
case VK_FORMAT_PVRTC2_4BPP_UNORM_BLOCK_IMG:
|
||||
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_UNORM_BLOCK_EXT:
|
||||
case VK_FORMAT_ASTC_3x3x3_SRGB_BLOCK_EXT:
|
||||
case VK_FORMAT_ASTC_3x3x3_SFLOAT_BLOCK_EXT:
|
||||
case VK_FORMAT_ASTC_4x3x3_UNORM_BLOCK_EXT:
|
||||
case VK_FORMAT_ASTC_4x3x3_SRGB_BLOCK_EXT:
|
||||
case VK_FORMAT_ASTC_4x3x3_SFLOAT_BLOCK_EXT:
|
||||
case VK_FORMAT_ASTC_4x4x3_UNORM_BLOCK_EXT:
|
||||
case VK_FORMAT_ASTC_4x4x3_SRGB_BLOCK_EXT:
|
||||
case VK_FORMAT_ASTC_4x4x3_SFLOAT_BLOCK_EXT:
|
||||
case VK_FORMAT_ASTC_4x4x4_UNORM_BLOCK_EXT:
|
||||
case VK_FORMAT_ASTC_4x4x4_SRGB_BLOCK_EXT:
|
||||
case VK_FORMAT_ASTC_4x4x4_SFLOAT_BLOCK_EXT:
|
||||
case VK_FORMAT_ASTC_5x4x4_UNORM_BLOCK_EXT:
|
||||
case VK_FORMAT_ASTC_5x4x4_SRGB_BLOCK_EXT:
|
||||
case VK_FORMAT_ASTC_5x4x4_SFLOAT_BLOCK_EXT:
|
||||
case VK_FORMAT_ASTC_5x5x4_UNORM_BLOCK_EXT:
|
||||
case VK_FORMAT_ASTC_5x5x4_SRGB_BLOCK_EXT:
|
||||
case VK_FORMAT_ASTC_5x5x4_SFLOAT_BLOCK_EXT:
|
||||
case VK_FORMAT_ASTC_5x5x5_UNORM_BLOCK_EXT:
|
||||
case VK_FORMAT_ASTC_5x5x5_SRGB_BLOCK_EXT:
|
||||
case VK_FORMAT_ASTC_5x5x5_SFLOAT_BLOCK_EXT:
|
||||
case VK_FORMAT_ASTC_6x5x5_UNORM_BLOCK_EXT:
|
||||
case VK_FORMAT_ASTC_6x5x5_SRGB_BLOCK_EXT:
|
||||
case VK_FORMAT_ASTC_6x5x5_SFLOAT_BLOCK_EXT:
|
||||
case VK_FORMAT_ASTC_6x6x5_UNORM_BLOCK_EXT:
|
||||
case VK_FORMAT_ASTC_6x6x5_SRGB_BLOCK_EXT:
|
||||
case VK_FORMAT_ASTC_6x6x5_SFLOAT_BLOCK_EXT:
|
||||
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_A1B5G5R5_UNORM_PACK16_KHR:
|
||||
case VK_FORMAT_A8_UNORM_KHR:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
@ -2,11 +2,11 @@
|
|||
#define _VKFORMAT_ENUM_H_
|
||||
|
||||
/***************************** Do not edit. *****************************
|
||||
Automatically generated from vulkan_core.h version 151 by mkvkformatfiles.
|
||||
Automatically generated from vulkan_core.h version 267 by mkvkformatfiles.
|
||||
*************************************************************************/
|
||||
|
||||
/*
|
||||
** Copyright (c) 2015-2020 The Khronos Group Inc.
|
||||
** Copyright 2015-2023 The Khronos Group Inc.
|
||||
**
|
||||
** SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
@ -238,6 +238,26 @@ typedef enum VkFormat {
|
|||
VK_FORMAT_G16_B16_R16_3PLANE_422_UNORM = 1000156031,
|
||||
VK_FORMAT_G16_B16R16_2PLANE_422_UNORM = 1000156032,
|
||||
VK_FORMAT_G16_B16_R16_3PLANE_444_UNORM = 1000156033,
|
||||
VK_FORMAT_G8_B8R8_2PLANE_444_UNORM = 1000330000,
|
||||
VK_FORMAT_G10X6_B10X6R10X6_2PLANE_444_UNORM_3PACK16 = 1000330001,
|
||||
VK_FORMAT_G12X4_B12X4R12X4_2PLANE_444_UNORM_3PACK16 = 1000330002,
|
||||
VK_FORMAT_G16_B16R16_2PLANE_444_UNORM = 1000330003,
|
||||
VK_FORMAT_A4R4G4B4_UNORM_PACK16 = 1000340000,
|
||||
VK_FORMAT_A4B4G4R4_UNORM_PACK16 = 1000340001,
|
||||
VK_FORMAT_ASTC_4x4_SFLOAT_BLOCK = 1000066000,
|
||||
VK_FORMAT_ASTC_5x4_SFLOAT_BLOCK = 1000066001,
|
||||
VK_FORMAT_ASTC_5x5_SFLOAT_BLOCK = 1000066002,
|
||||
VK_FORMAT_ASTC_6x5_SFLOAT_BLOCK = 1000066003,
|
||||
VK_FORMAT_ASTC_6x6_SFLOAT_BLOCK = 1000066004,
|
||||
VK_FORMAT_ASTC_8x5_SFLOAT_BLOCK = 1000066005,
|
||||
VK_FORMAT_ASTC_8x6_SFLOAT_BLOCK = 1000066006,
|
||||
VK_FORMAT_ASTC_8x8_SFLOAT_BLOCK = 1000066007,
|
||||
VK_FORMAT_ASTC_10x5_SFLOAT_BLOCK = 1000066008,
|
||||
VK_FORMAT_ASTC_10x6_SFLOAT_BLOCK = 1000066009,
|
||||
VK_FORMAT_ASTC_10x8_SFLOAT_BLOCK = 1000066010,
|
||||
VK_FORMAT_ASTC_10x10_SFLOAT_BLOCK = 1000066011,
|
||||
VK_FORMAT_ASTC_12x10_SFLOAT_BLOCK = 1000066012,
|
||||
VK_FORMAT_ASTC_12x12_SFLOAT_BLOCK = 1000066013,
|
||||
VK_FORMAT_PVRTC1_2BPP_UNORM_BLOCK_IMG = 1000054000,
|
||||
VK_FORMAT_PVRTC1_4BPP_UNORM_BLOCK_IMG = 1000054001,
|
||||
VK_FORMAT_PVRTC2_2BPP_UNORM_BLOCK_IMG = 1000054002,
|
||||
|
@ -246,20 +266,6 @@ typedef enum VkFormat {
|
|||
VK_FORMAT_PVRTC1_4BPP_SRGB_BLOCK_IMG = 1000054005,
|
||||
VK_FORMAT_PVRTC2_2BPP_SRGB_BLOCK_IMG = 1000054006,
|
||||
VK_FORMAT_PVRTC2_4BPP_SRGB_BLOCK_IMG = 1000054007,
|
||||
VK_FORMAT_ASTC_4x4_SFLOAT_BLOCK_EXT = 1000066000,
|
||||
VK_FORMAT_ASTC_5x4_SFLOAT_BLOCK_EXT = 1000066001,
|
||||
VK_FORMAT_ASTC_5x5_SFLOAT_BLOCK_EXT = 1000066002,
|
||||
VK_FORMAT_ASTC_6x5_SFLOAT_BLOCK_EXT = 1000066003,
|
||||
VK_FORMAT_ASTC_6x6_SFLOAT_BLOCK_EXT = 1000066004,
|
||||
VK_FORMAT_ASTC_8x5_SFLOAT_BLOCK_EXT = 1000066005,
|
||||
VK_FORMAT_ASTC_8x6_SFLOAT_BLOCK_EXT = 1000066006,
|
||||
VK_FORMAT_ASTC_8x8_SFLOAT_BLOCK_EXT = 1000066007,
|
||||
VK_FORMAT_ASTC_10x5_SFLOAT_BLOCK_EXT = 1000066008,
|
||||
VK_FORMAT_ASTC_10x6_SFLOAT_BLOCK_EXT = 1000066009,
|
||||
VK_FORMAT_ASTC_10x8_SFLOAT_BLOCK_EXT = 1000066010,
|
||||
VK_FORMAT_ASTC_10x10_SFLOAT_BLOCK_EXT = 1000066011,
|
||||
VK_FORMAT_ASTC_12x10_SFLOAT_BLOCK_EXT = 1000066012,
|
||||
VK_FORMAT_ASTC_12x12_SFLOAT_BLOCK_EXT = 1000066013,
|
||||
VK_FORMAT_ASTC_3x3x3_UNORM_BLOCK_EXT = 1000288000,
|
||||
VK_FORMAT_ASTC_3x3x3_SRGB_BLOCK_EXT = 1000288001,
|
||||
VK_FORMAT_ASTC_3x3x3_SFLOAT_BLOCK_EXT = 1000288002,
|
||||
|
@ -290,10 +296,18 @@ 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_A4R4G4B4_UNORM_PACK16_EXT = 1000340000,
|
||||
VK_FORMAT_A4B4G4R4_UNORM_PACK16_EXT = 1000340001,
|
||||
VK_FORMAT_R16G16_S10_5_NV = 1000464000,
|
||||
VK_FORMAT_A1B5G5R5_UNORM_PACK16_KHR = 1000470000,
|
||||
VK_FORMAT_A8_UNORM_KHR = 1000470001,
|
||||
VK_FORMAT_MAX_ENUM = 0x7FFFFFFF
|
||||
} VkFormat;
|
||||
#if defined(_MSC_VER) && _MSC_VER < 1900 // Older than VS 2015.
|
||||
typedef unsigned __int32 VkFlags;
|
||||
#else
|
||||
#include <stdint.h>
|
||||
typedef uint64_t VkFlags64;
|
||||
#endif
|
||||
|
||||
|
||||
#define VK_FORMAT_MAX_STANDARD_ENUM 184
|
||||
|
||||
|
|
|
@ -0,0 +1,50 @@
|
|||
diff --git a/thirdparty/libktx/lib/basis_transcode.cpp b/thirdparty/libktx/lib/basis_transcode.cpp
|
||||
index ca68545e4a..d7ecb7a0fd 100644
|
||||
--- a/thirdparty/libktx/lib/basis_transcode.cpp
|
||||
+++ b/thirdparty/libktx/lib/basis_transcode.cpp
|
||||
@@ -29,9 +29,9 @@
|
||||
#include "vkformat_enum.h"
|
||||
#include "vk_format.h"
|
||||
#include "basis_sgd.h"
|
||||
-#include "basisu/transcoder/basisu_file_headers.h"
|
||||
-#include "basisu/transcoder/basisu_transcoder.h"
|
||||
-#include "basisu/transcoder/basisu_transcoder_internal.h"
|
||||
+#include "transcoder/basisu_file_headers.h"
|
||||
+#include "transcoder/basisu_transcoder.h"
|
||||
+#include "transcoder/basisu_transcoder_internal.h"
|
||||
|
||||
#undef DECLARE_PRIVATE
|
||||
#undef DECLARE_PROTECTED
|
||||
diff --git a/thirdparty/libktx/lib/dfdutils/vk2dfd.inl b/thirdparty/libktx/lib/dfdutils/vk2dfd.inl
|
||||
index 85d53202a5..25c7a2c238 100644
|
||||
--- a/thirdparty/libktx/lib/dfdutils/vk2dfd.inl
|
||||
+++ b/thirdparty/libktx/lib/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);
|
||||
case VK_FORMAT_PVRTC2_4BPP_SRGB_BLOCK_IMG: return createDFDCompressed(c_PVRTC2, 4, 4, 1, s_SRGB);
|
||||
+#if 0
|
||||
case VK_FORMAT_ASTC_3x3x3_UNORM_BLOCK_EXT: return createDFDCompressed(c_ASTC, 3, 3, 3, s_UNORM);
|
||||
case VK_FORMAT_ASTC_3x3x3_SRGB_BLOCK_EXT: return createDFDCompressed(c_ASTC, 3, 3, 3, s_SRGB);
|
||||
case VK_FORMAT_ASTC_3x3x3_SFLOAT_BLOCK_EXT: return createDFDCompressed(c_ASTC, 3, 3, 3, s_SFLOAT);
|
||||
@@ -400,6 +401,7 @@ case VK_FORMAT_ASTC_6x6x5_SFLOAT_BLOCK_EXT: return createDFDCompressed(c_ASTC, 6
|
||||
case VK_FORMAT_ASTC_6x6x6_UNORM_BLOCK_EXT: return createDFDCompressed(c_ASTC, 6, 6, 6, s_UNORM);
|
||||
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_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/lib/miniz_wrapper.cpp b/thirdparty/libktx/lib/miniz_wrapper.cpp
|
||||
index 07920c4809..cbd7da540a 100644
|
||||
--- a/thirdparty/libktx/lib/miniz_wrapper.cpp
|
||||
+++ b/thirdparty/libktx/lib/miniz_wrapper.cpp
|
||||
@@ -30,7 +30,7 @@
|
||||
#pragma GCC diagnostic ignored "-Wextra"
|
||||
#pragma GCC diagnostic ignored "-Wmisleading-indentation"
|
||||
#endif
|
||||
-#include "basisu/encoder/basisu_miniz.h"
|
||||
+#include "encoder/basisu_miniz.h"
|
||||
#ifdef __GNUC__
|
||||
#pragma GCC diagnostic pop
|
||||
#endif
|
Loading…
Reference in New Issue