initial commit, 4.5 stable
Some checks failed
🔗 GHA / 📊 Static checks (push) Has been cancelled
🔗 GHA / 🤖 Android (push) Has been cancelled
🔗 GHA / 🍏 iOS (push) Has been cancelled
🔗 GHA / 🐧 Linux (push) Has been cancelled
🔗 GHA / 🍎 macOS (push) Has been cancelled
🔗 GHA / 🏁 Windows (push) Has been cancelled
🔗 GHA / 🌐 Web (push) Has been cancelled
Some checks failed
🔗 GHA / 📊 Static checks (push) Has been cancelled
🔗 GHA / 🤖 Android (push) Has been cancelled
🔗 GHA / 🍏 iOS (push) Has been cancelled
🔗 GHA / 🐧 Linux (push) Has been cancelled
🔗 GHA / 🍎 macOS (push) Has been cancelled
🔗 GHA / 🏁 Windows (push) Has been cancelled
🔗 GHA / 🌐 Web (push) Has been cancelled
This commit is contained in:
85
thirdparty/libktx/lib/basis_sgd.h
vendored
Normal file
85
thirdparty/libktx/lib/basis_sgd.h
vendored
Normal file
@@ -0,0 +1,85 @@
|
||||
/* -*- tab-width: 4; -*- */
|
||||
/* vi: set sw=2 ts=4 expandtab textwidth=70: */
|
||||
|
||||
/*
|
||||
* Copyright 2019-2020 The Khronos Group Inc.
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
/**
|
||||
* @internal
|
||||
* @file basisu_sgd.h
|
||||
* @~English
|
||||
*
|
||||
* @brief Declare global data for Basis LZ supercompression with ETC1S.
|
||||
*
|
||||
* These functions are private and should not be used outside the library.
|
||||
*/
|
||||
|
||||
#ifndef _BASIS_SGD_H_
|
||||
#define _BASIS_SGD_H_
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
// 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 { ETC1S_P_FRAME = 0x02 };
|
||||
|
||||
typedef uint32_t buFlags;
|
||||
|
||||
typedef struct ktxBasisLzGlobalHeader {
|
||||
uint16_t endpointCount;
|
||||
uint16_t selectorCount;
|
||||
uint32_t endpointsByteLength;
|
||||
uint32_t selectorsByteLength;
|
||||
uint32_t tablesByteLength;
|
||||
uint32_t extendedByteLength;
|
||||
} ktxBasisLzGlobalHeader;
|
||||
|
||||
// This header is followed by imageCount "slice" descriptions.
|
||||
|
||||
// 1, or 2 slices per image (i.e. layer, face & slice).
|
||||
// These offsets are relative to start of a mip level as given by the
|
||||
// main levelIndex.
|
||||
typedef struct ktxBasisLzEtc1sImageDesc {
|
||||
buFlags imageFlags;
|
||||
uint32_t rgbSliceByteOffset;
|
||||
uint32_t rgbSliceByteLength;
|
||||
uint32_t alphaSliceByteOffset;
|
||||
uint32_t alphaSliceByteLength;
|
||||
} ktxBasisLzEtc1sImageDesc;
|
||||
|
||||
#define BGD_ETC1S_IMAGE_DESCS(bgd) \
|
||||
reinterpret_cast<ktxBasisLzEtc1sImageDesc*>(bgd + sizeof(ktxBasisLzGlobalHeader))
|
||||
|
||||
// The are followed in the global data by these ...
|
||||
// uint8_t[endpointsByteLength] endpointsData;
|
||||
// uint8_t[selectorsByteLength] selectorsData;
|
||||
// uint8_t[tablesByteLength] tablesData;
|
||||
|
||||
#define BGD_ENDPOINTS_ADDR(bgd, imageCount) \
|
||||
(bgd + sizeof(ktxBasisLzGlobalHeader) + sizeof(ktxBasisLzEtc1sImageDesc) * imageCount)
|
||||
|
||||
#define BGD_SELECTORS_ADDR(bgd, bgdh, imageCount) (BGD_ENDPOINTS_ADDR(bgd, imageCount) + bgdh.endpointsByteLength)
|
||||
|
||||
#define BGD_TABLES_ADDR(bgd, bgdh, imageCount) (BGD_SELECTORS_ADDR(bgd, bgdh, imageCount) + bgdh.selectorsByteLength)
|
||||
|
||||
#define BGD_EXTENDED_ADDR(bgd, bgdh, imageCount) (BGD_TABLES_ADDR(bgd, bgdh, imageCount) + bgdh.tablesByteLength)
|
||||
|
||||
// Just because this is a convenient place to put it for basis_{en,trans}code.
|
||||
enum alpha_content_e {
|
||||
eNone,
|
||||
eAlpha,
|
||||
eGreen
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _BASIS_SGD_H_ */
|
744
thirdparty/libktx/lib/basis_transcode.cpp
vendored
Normal file
744
thirdparty/libktx/lib/basis_transcode.cpp
vendored
Normal file
@@ -0,0 +1,744 @@
|
||||
/* -*- tab-width: 4; -*- */
|
||||
/* vi: set sw=2 ts=4 expandtab: */
|
||||
|
||||
/*
|
||||
* Copyright 2019-2020 The Khronos Group Inc.
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
/**
|
||||
* @internal
|
||||
* @file
|
||||
* @~English
|
||||
*
|
||||
* @brief Functions for transcoding Basis Universal BasisLZ/ETC1S and UASTC textures.
|
||||
*
|
||||
* Two worlds collide here too. More uglyness!
|
||||
*
|
||||
* @author Mark Callow, www.edgewise-consulting.com
|
||||
*/
|
||||
|
||||
#include <inttypes.h>
|
||||
#include <stdio.h>
|
||||
#include <KHR/khr_df.h>
|
||||
|
||||
#include "dfdutils/dfd.h"
|
||||
#include "ktx.h"
|
||||
#include "ktxint.h"
|
||||
#include "texture2.h"
|
||||
#include "vkformat_enum.h"
|
||||
#include "vk_format.h"
|
||||
#include "basis_sgd.h"
|
||||
#include "transcoder/basisu_file_headers.h"
|
||||
#include "transcoder/basisu_transcoder.h"
|
||||
#include "transcoder/basisu_transcoder_internal.h"
|
||||
|
||||
#undef DECLARE_PRIVATE
|
||||
#undef DECLARE_PROTECTED
|
||||
#define DECLARE_PRIVATE(n,t2) ktxTexture2_private& n = *(t2->_private)
|
||||
#define DECLARE_PROTECTED(n,t2) ktxTexture_protected& n = *(t2->_protected)
|
||||
|
||||
using namespace basisu;
|
||||
using namespace basist;
|
||||
|
||||
inline bool isPow2(uint32_t x) { return x && ((x & (x - 1U)) == 0U); }
|
||||
|
||||
inline bool isPow2(uint64_t x) { return x && ((x & (x - 1U)) == 0U); }
|
||||
|
||||
KTX_error_code
|
||||
ktxTexture2_transcodeLzEtc1s(ktxTexture2* This,
|
||||
alpha_content_e alphaContent,
|
||||
ktxTexture2* prototype,
|
||||
ktx_transcode_fmt_e outputFormat,
|
||||
ktx_transcode_flags transcodeFlags);
|
||||
KTX_error_code
|
||||
ktxTexture2_transcodeUastc(ktxTexture2* This,
|
||||
alpha_content_e alphaContent,
|
||||
ktxTexture2* prototype,
|
||||
ktx_transcode_fmt_e outputFormat,
|
||||
ktx_transcode_flags transcodeFlags);
|
||||
|
||||
/**
|
||||
* @memberof ktxTexture2
|
||||
* @ingroup reader
|
||||
* @~English
|
||||
* @brief Transcode a KTX2 texture with BasisLZ/ETC1S or UASTC images.
|
||||
*
|
||||
* If the texture contains BasisLZ supercompressed images, Inflates them from
|
||||
* back to ETC1S then transcodes them to the specified block-compressed
|
||||
* format. If the texture contains UASTC images, inflates them, if they have been
|
||||
* supercompressed with zstd, then transcodes then to the specified format, The
|
||||
* transcoded images replace the original images and the texture's fields including
|
||||
* the DFD are modified to reflect the new format.
|
||||
*
|
||||
* These types of textures must be transcoded to a desired target
|
||||
* block-compressed format before they can be uploaded to a GPU via a
|
||||
* graphics API.
|
||||
*
|
||||
* The following block compressed transcode targets are available: @c KTX_TTF_ETC1_RGB,
|
||||
* @c KTX_TTF_ETC2_RGBA, @c KTX_TTF_BC1_RGB, @c KTX_TTF_BC3_RGBA,
|
||||
* @c KTX_TTF_BC4_R, @c KTX_TTF_BC5_RG, @c KTX_TTF_BC7_RGBA,
|
||||
* @c @c KTX_TTF_PVRTC1_4_RGB, @c KTX_TTF_PVRTC1_4_RGBA,
|
||||
* @c KTX_TTF_PVRTC2_4_RGB, @c KTX_TTF_PVRTC2_4_RGBA, @c KTX_TTF_ASTC_4x4_RGBA,
|
||||
* @c KTX_TTF_ETC2_EAC_R11, @c KTX_TTF_ETC2_EAC_RG11, @c KTX_TTF_ETC and
|
||||
* @c KTX_TTF_BC1_OR_3.
|
||||
*
|
||||
* @c KTX_TTF_ETC automatically selects between @c KTX_TTF_ETC1_RGB and
|
||||
* @c KTX_TTF_ETC2_RGBA according to whether an alpha channel is available. @c KTX_TTF_BC1_OR_3
|
||||
* does likewise between @c KTX_TTF_BC1_RGB and @c KTX_TTF_BC3_RGBA. Note that if
|
||||
* @c KTX_TTF_PVRTC1_4_RGBA or @c KTX_TTF_PVRTC2_4_RGBA is specified and there is no alpha
|
||||
* channel @c KTX_TTF_PVRTC1_4_RGB or @c KTX_TTF_PVRTC2_4_RGB respectively will be selected.
|
||||
*
|
||||
* Transcoding to ATC & FXT1 formats is not supported by libktx as there
|
||||
* are no equivalent Vulkan formats.
|
||||
*
|
||||
* The following uncompressed transcode targets are also available: @c KTX_TTF_RGBA32,
|
||||
* @c KTX_TTF_RGB565, KTX_TTF_BGR565 and KTX_TTF_RGBA4444.
|
||||
*
|
||||
* The following @p transcodeFlags are available.
|
||||
*
|
||||
* @sa ktxtexture2_CompressBasis().
|
||||
*
|
||||
* @param[in] This pointer to the ktxTexture2 object of interest.
|
||||
* @param[in] outputFormat a value from the ktx_texture_transcode_fmt_e enum
|
||||
* specifying the target format.
|
||||
* @param[in] transcodeFlags bitfield of flags modifying the transcode
|
||||
* operation. @sa ktx_texture_decode_flags_e.
|
||||
*
|
||||
* @return KTX_SUCCESS on success, other KTX_* enum values on error.
|
||||
*
|
||||
* @exception KTX_FILE_DATA_ERROR
|
||||
* Supercompression global data is corrupted.
|
||||
* @exception KTX_INVALID_OPERATION
|
||||
* The texture's format is not transcodable (not
|
||||
* ETC1S/BasisLZ or UASTC).
|
||||
* @exception KTX_INVALID_OPERATION
|
||||
* Supercompression global data is missing, i.e.,
|
||||
* the texture object is invalid.
|
||||
* @exception KTX_INVALID_OPERATION
|
||||
* Image data is missing, i.e., the texture object
|
||||
* is invalid.
|
||||
* @exception KTX_INVALID_OPERATION
|
||||
* @p outputFormat is PVRTC1 but the texture does
|
||||
* does not have power-of-two dimensions.
|
||||
* @exception KTX_INVALID_VALUE @p outputFormat is invalid.
|
||||
* @exception KTX_TRANSCODE_FAILED
|
||||
* Something went wrong during transcoding.
|
||||
* @exception KTX_UNSUPPORTED_FEATURE
|
||||
* KTX_TF_PVRTC_DECODE_TO_NEXT_POW2 was requested
|
||||
* or the specified transcode target has not been
|
||||
* included in the library being used.
|
||||
* @exception KTX_OUT_OF_MEMORY Not enough memory to carry out transcoding.
|
||||
*/
|
||||
KTX_error_code
|
||||
ktxTexture2_TranscodeBasis(ktxTexture2* This,
|
||||
ktx_transcode_fmt_e outputFormat,
|
||||
ktx_transcode_flags transcodeFlags)
|
||||
{
|
||||
uint32_t* BDB = This->pDfd + 1;
|
||||
khr_df_model_e colorModel = (khr_df_model_e)KHR_DFDVAL(BDB, MODEL);
|
||||
if (colorModel != KHR_DF_MODEL_UASTC
|
||||
// Constructor has checked color model matches BASIS_LZ.
|
||||
&& This->supercompressionScheme != KTX_SS_BASIS_LZ)
|
||||
{
|
||||
return KTX_INVALID_OPERATION; // Not in a transcodable format.
|
||||
}
|
||||
|
||||
DECLARE_PRIVATE(priv, This);
|
||||
if (This->supercompressionScheme == KTX_SS_BASIS_LZ) {
|
||||
if (!priv._supercompressionGlobalData || priv._sgdByteLength == 0)
|
||||
return KTX_INVALID_OPERATION;
|
||||
}
|
||||
|
||||
if (transcodeFlags & KTX_TF_PVRTC_DECODE_TO_NEXT_POW2) {
|
||||
debug_printf("ktxTexture_TranscodeBasis: KTX_TF_PVRTC_DECODE_TO_NEXT_POW2 currently unsupported\n");
|
||||
return KTX_UNSUPPORTED_FEATURE;
|
||||
}
|
||||
|
||||
if (outputFormat == KTX_TTF_PVRTC1_4_RGB
|
||||
|| outputFormat == KTX_TTF_PVRTC1_4_RGBA) {
|
||||
if ((!isPow2(This->baseWidth)) || (!isPow2(This->baseHeight))) {
|
||||
debug_printf("ktxTexture_TranscodeBasis: PVRTC1 only supports power of 2 dimensions\n");
|
||||
return KTX_INVALID_OPERATION;
|
||||
}
|
||||
}
|
||||
|
||||
const bool srgb = (KHR_DFDVAL(BDB, TRANSFER) == KHR_DF_TRANSFER_SRGB);
|
||||
alpha_content_e alphaContent = eNone;
|
||||
if (colorModel == KHR_DF_MODEL_ETC1S) {
|
||||
if (KHR_DFDSAMPLECOUNT(BDB) == 2) {
|
||||
uint32_t channelId = KHR_DFDSVAL(BDB, 1, CHANNELID);
|
||||
if (channelId == KHR_DF_CHANNEL_ETC1S_AAA) {
|
||||
alphaContent = eAlpha;
|
||||
} else if (channelId == KHR_DF_CHANNEL_ETC1S_GGG){
|
||||
alphaContent = eGreen;
|
||||
} else {
|
||||
return KTX_FILE_DATA_ERROR;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
uint32_t channelId = KHR_DFDSVAL(BDB, 0, CHANNELID);
|
||||
if (channelId == KHR_DF_CHANNEL_UASTC_RGBA)
|
||||
alphaContent = eAlpha;
|
||||
else if (channelId == KHR_DF_CHANNEL_UASTC_RRRG)
|
||||
alphaContent = eGreen;
|
||||
}
|
||||
|
||||
VkFormat vkFormat;
|
||||
|
||||
// Do some format mapping.
|
||||
switch (outputFormat) {
|
||||
case KTX_TTF_BC1_OR_3:
|
||||
outputFormat = alphaContent != eNone ? KTX_TTF_BC3_RGBA
|
||||
: KTX_TTF_BC1_RGB;
|
||||
break;
|
||||
case KTX_TTF_ETC:
|
||||
outputFormat = alphaContent != eNone ? KTX_TTF_ETC2_RGBA
|
||||
: KTX_TTF_ETC1_RGB;
|
||||
break;
|
||||
case KTX_TTF_PVRTC1_4_RGBA:
|
||||
// This transcoder does not write opaque alpha blocks.
|
||||
outputFormat = alphaContent != eNone ? KTX_TTF_PVRTC1_4_RGBA
|
||||
: KTX_TTF_PVRTC1_4_RGB;
|
||||
break;
|
||||
case KTX_TTF_PVRTC2_4_RGBA:
|
||||
// This transcoder does not write opaque alpha blocks.
|
||||
outputFormat = alphaContent != eNone ? KTX_TTF_PVRTC2_4_RGBA
|
||||
: KTX_TTF_PVRTC2_4_RGB;
|
||||
break;
|
||||
default:
|
||||
/*NOP*/;
|
||||
}
|
||||
|
||||
switch (outputFormat) {
|
||||
case KTX_TTF_ETC1_RGB:
|
||||
vkFormat = srgb ? VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK
|
||||
: VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK;
|
||||
break;
|
||||
case KTX_TTF_ETC2_RGBA:
|
||||
vkFormat = srgb ? VK_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK
|
||||
: VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK;
|
||||
break;
|
||||
case KTX_TTF_ETC2_EAC_R11:
|
||||
vkFormat = VK_FORMAT_EAC_R11_UNORM_BLOCK;
|
||||
break;
|
||||
case KTX_TTF_ETC2_EAC_RG11:
|
||||
vkFormat = VK_FORMAT_EAC_R11G11_UNORM_BLOCK;
|
||||
break;
|
||||
case KTX_TTF_BC1_RGB:
|
||||
// Transcoding doesn't support BC1 alpha.
|
||||
vkFormat = srgb ? VK_FORMAT_BC1_RGB_SRGB_BLOCK
|
||||
: VK_FORMAT_BC1_RGB_UNORM_BLOCK;
|
||||
break;
|
||||
case KTX_TTF_BC3_RGBA:
|
||||
vkFormat = srgb ? VK_FORMAT_BC3_SRGB_BLOCK
|
||||
: VK_FORMAT_BC3_UNORM_BLOCK;
|
||||
break;
|
||||
case KTX_TTF_BC4_R:
|
||||
vkFormat = VK_FORMAT_BC4_UNORM_BLOCK;
|
||||
break;
|
||||
case KTX_TTF_BC5_RG:
|
||||
vkFormat = VK_FORMAT_BC5_UNORM_BLOCK;
|
||||
break;
|
||||
case KTX_TTF_PVRTC1_4_RGB:
|
||||
case KTX_TTF_PVRTC1_4_RGBA:
|
||||
vkFormat = srgb ? VK_FORMAT_PVRTC1_4BPP_SRGB_BLOCK_IMG
|
||||
: VK_FORMAT_PVRTC1_4BPP_UNORM_BLOCK_IMG;
|
||||
break;
|
||||
case KTX_TTF_PVRTC2_4_RGB:
|
||||
case KTX_TTF_PVRTC2_4_RGBA:
|
||||
vkFormat = srgb ? VK_FORMAT_PVRTC2_4BPP_SRGB_BLOCK_IMG
|
||||
: VK_FORMAT_PVRTC2_4BPP_UNORM_BLOCK_IMG;
|
||||
break;
|
||||
case KTX_TTF_BC7_RGBA:
|
||||
vkFormat = srgb ? VK_FORMAT_BC7_SRGB_BLOCK
|
||||
: VK_FORMAT_BC7_UNORM_BLOCK;
|
||||
break;
|
||||
case KTX_TTF_ASTC_4x4_RGBA:
|
||||
vkFormat = srgb ? VK_FORMAT_ASTC_4x4_SRGB_BLOCK
|
||||
: VK_FORMAT_ASTC_4x4_UNORM_BLOCK;
|
||||
break;
|
||||
case KTX_TTF_RGB565:
|
||||
vkFormat = VK_FORMAT_R5G6B5_UNORM_PACK16;
|
||||
break;
|
||||
case KTX_TTF_BGR565:
|
||||
vkFormat = VK_FORMAT_B5G6R5_UNORM_PACK16;
|
||||
break;
|
||||
case KTX_TTF_RGBA4444:
|
||||
vkFormat = VK_FORMAT_R4G4B4A4_UNORM_PACK16;
|
||||
break;
|
||||
case KTX_TTF_RGBA32:
|
||||
vkFormat = srgb ? VK_FORMAT_R8G8B8A8_SRGB
|
||||
: VK_FORMAT_R8G8B8A8_UNORM;
|
||||
break;
|
||||
default:
|
||||
return KTX_INVALID_VALUE;
|
||||
}
|
||||
|
||||
basis_tex_format textureFormat;
|
||||
if (colorModel == KHR_DF_MODEL_UASTC)
|
||||
textureFormat = basis_tex_format::cUASTC4x4;
|
||||
else
|
||||
textureFormat = basis_tex_format::cETC1S;
|
||||
|
||||
if (!basis_is_format_supported((transcoder_texture_format)outputFormat,
|
||||
textureFormat)) {
|
||||
return KTX_UNSUPPORTED_FEATURE;
|
||||
}
|
||||
|
||||
|
||||
// Create a prototype texture to use for calculating sizes in the target
|
||||
// format and, as useful side effects, provide us with a properly sized
|
||||
// data allocation and the DFD for the target format.
|
||||
ktxTextureCreateInfo createInfo;
|
||||
createInfo.glInternalformat = 0;
|
||||
createInfo.vkFormat = vkFormat;
|
||||
createInfo.baseWidth = This->baseWidth;
|
||||
createInfo.baseHeight = This->baseHeight;
|
||||
createInfo.baseDepth = This->baseDepth;
|
||||
createInfo.generateMipmaps = This->generateMipmaps;
|
||||
createInfo.isArray = This->isArray;
|
||||
createInfo.numDimensions = This->numDimensions;
|
||||
createInfo.numFaces = This->numFaces;
|
||||
createInfo.numLayers = This->numLayers;
|
||||
createInfo.numLevels = This->numLevels;
|
||||
createInfo.pDfd = nullptr;
|
||||
|
||||
KTX_error_code result;
|
||||
ktxTexture2* prototype;
|
||||
result = ktxTexture2_Create(&createInfo, KTX_TEXTURE_CREATE_ALLOC_STORAGE,
|
||||
&prototype);
|
||||
|
||||
if (result != KTX_SUCCESS) {
|
||||
assert(result == KTX_OUT_OF_MEMORY); // The only run time error
|
||||
return result;
|
||||
}
|
||||
|
||||
if (!This->pData) {
|
||||
if (ktxTexture_isActiveStream((ktxTexture*)This)) {
|
||||
// Load pending. Complete it.
|
||||
result = ktxTexture2_LoadImageData(This, NULL, 0);
|
||||
if (result != KTX_SUCCESS)
|
||||
{
|
||||
ktxTexture2_Destroy(prototype);
|
||||
return result;
|
||||
}
|
||||
} else {
|
||||
// No data to transcode.
|
||||
ktxTexture2_Destroy(prototype);
|
||||
return KTX_INVALID_OPERATION;
|
||||
}
|
||||
}
|
||||
|
||||
// Transcoder global initialization. Requires ~9 milliseconds when compiled
|
||||
// and executed natively on a Core i7 2.2 GHz. If this is too slow, the
|
||||
// tables it computes can easily be moved to be compiled in.
|
||||
static bool transcoderInitialized;
|
||||
if (!transcoderInitialized) {
|
||||
basisu_transcoder_init();
|
||||
transcoderInitialized = true;
|
||||
}
|
||||
|
||||
if (textureFormat == basis_tex_format::cETC1S) {
|
||||
result = ktxTexture2_transcodeLzEtc1s(This, alphaContent,
|
||||
prototype, outputFormat,
|
||||
transcodeFlags);
|
||||
} else {
|
||||
result = ktxTexture2_transcodeUastc(This, alphaContent,
|
||||
prototype, outputFormat,
|
||||
transcodeFlags);
|
||||
}
|
||||
|
||||
if (result == KTX_SUCCESS) {
|
||||
// Fix up the current texture
|
||||
DECLARE_PROTECTED(thisPrtctd, This);
|
||||
DECLARE_PRIVATE(protoPriv, prototype);
|
||||
DECLARE_PROTECTED(protoPrtctd, prototype);
|
||||
memcpy(&thisPrtctd._formatSize, &protoPrtctd._formatSize,
|
||||
sizeof(ktxFormatSize));
|
||||
This->vkFormat = vkFormat;
|
||||
This->isCompressed = prototype->isCompressed;
|
||||
This->supercompressionScheme = KTX_SS_NONE;
|
||||
priv._requiredLevelAlignment = protoPriv._requiredLevelAlignment;
|
||||
// Copy the levelIndex from the prototype to This.
|
||||
memcpy(priv._levelIndex, protoPriv._levelIndex,
|
||||
This->numLevels * sizeof(ktxLevelIndexEntry));
|
||||
// Move the DFD and data from the prototype to This.
|
||||
free(This->pDfd);
|
||||
This->pDfd = prototype->pDfd;
|
||||
prototype->pDfd = 0;
|
||||
free(This->pData);
|
||||
This->pData = prototype->pData;
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
* @memberof ktxTexture2 @private
|
||||
* @ingroup reader
|
||||
* @~English
|
||||
* @brief Transcode a KTX2 texture with BasisLZ supercompressed ETC1S images.
|
||||
*
|
||||
* Inflates the images from BasisLZ supercompression back to ETC1S
|
||||
* then transcodes them to the specified block-compressed format. The
|
||||
* transcoded images replace the original images and the texture's fields
|
||||
* including the DFD are modified to reflect the new format.
|
||||
*
|
||||
* BasisLZ supercompressed textures must be transcoded to a desired target
|
||||
* block-compressed format before they can be uploaded to a GPU via a graphics
|
||||
* API.
|
||||
*
|
||||
* The following block compressed transcode targets are available: @c KTX_TTF_ETC1_RGB,
|
||||
* @c KTX_TTF_ETC2_RGBA, @c KTX_TTF_BC1_RGB, @c KTX_TTF_BC3_RGBA,
|
||||
* @c KTX_TTF_BC4_R, @c KTX_TTF_BC5_RG, @c KTX_TTF_BC7_RGBA,
|
||||
* @c @c KTX_TTF_PVRTC1_4_RGB, @c KTX_TTF_PVRTC1_4_RGBA,
|
||||
* @c KTX_TTF_PVRTC2_4_RGB, @c KTX_TTF_PVRTC2_4_RGBA, @c KTX_TTF_ASTC_4x4_RGBA,
|
||||
* @c KTX_TTF_ETC2_EAC_R11, @c KTX_TTF_ETC2_EAC_RG11, @c KTX_TTF_ETC and
|
||||
* @c KTX_TTF_BC1_OR_3.
|
||||
*
|
||||
* @c KTX_TTF_ETC automatically selects between @c KTX_TTF_ETC1_RGB and
|
||||
* @c KTX_TTF_ETC2_RGBA according to whether an alpha channel is available. @c KTX_TTF_BC1_OR_3
|
||||
* does likewise between @c KTX_TTF_BC1_RGB and @c KTX_TTF_BC3_RGBA. Note that if
|
||||
* @c KTX_TTF_PVRTC1_4_RGBA or @c KTX_TTF_PVRTC2_4_RGBA is specified and there is no alpha
|
||||
* channel @c KTX_TTF_PVRTC1_4_RGB or @c KTX_TTF_PVRTC2_4_RGB respectively will be selected.
|
||||
*
|
||||
* ATC & FXT1 formats are not supported by KTX2 & libktx as there are no equivalent Vulkan formats.
|
||||
*
|
||||
* The following uncompressed transcode targets are also available: @c KTX_TTF_RGBA32,
|
||||
* @c KTX_TTF_RGB565, KTX_TTF_BGR565 and KTX_TTF_RGBA4444.
|
||||
*
|
||||
* The following @p transcodeFlags are available.
|
||||
*
|
||||
* @sa ktxtexture2_CompressBasis().
|
||||
*
|
||||
* @param[in] This pointer to the ktxTexture2 object of interest.
|
||||
* @param[in] outputFormat a value from the ktx_texture_transcode_fmt_e enum
|
||||
* specifying the target format.
|
||||
* @param[in] transcodeFlags bitfield of flags modifying the transcode
|
||||
* operation. @sa ktx_texture_decode_flags_e.
|
||||
*
|
||||
* @return KTX_SUCCESS on success, other KTX_* enum values on error.
|
||||
*
|
||||
* @exception KTX_FILE_DATA_ERROR
|
||||
* Supercompression global data is corrupted.
|
||||
* @exception KTX_INVALID_OPERATION
|
||||
* The texture's format is not transcodable (not
|
||||
* ETC1S/BasisLZ or UASTC).
|
||||
* @exception KTX_INVALID_OPERATION
|
||||
* Supercompression global data is missing, i.e.,
|
||||
* the texture object is invalid.
|
||||
* @exception KTX_INVALID_OPERATION
|
||||
* Image data is missing, i.e., the texture object
|
||||
* is invalid.
|
||||
* @exception KTX_INVALID_OPERATION
|
||||
* @p outputFormat is PVRTC1 but the texture does
|
||||
* does not have power-of-two dimensions.
|
||||
* @exception KTX_INVALID_VALUE @p outputFormat is invalid.
|
||||
* @exception KTX_TRANSCODE_FAILED
|
||||
* Something went wrong during transcoding. The
|
||||
* texture object will be corrupted.
|
||||
* @exception KTX_UNSUPPORTED_FEATURE
|
||||
* KTX_TF_PVRTC_DECODE_TO_NEXT_POW2 was requested
|
||||
* or the specified transcode target has not been
|
||||
* included in the library being used.
|
||||
* @exception KTX_OUT_OF_MEMORY Not enough memory to carry out transcoding.
|
||||
*/
|
||||
KTX_error_code
|
||||
ktxTexture2_transcodeLzEtc1s(ktxTexture2* This,
|
||||
alpha_content_e alphaContent,
|
||||
ktxTexture2* prototype,
|
||||
ktx_transcode_fmt_e outputFormat,
|
||||
ktx_transcode_flags transcodeFlags)
|
||||
{
|
||||
DECLARE_PRIVATE(priv, This);
|
||||
DECLARE_PRIVATE(protoPriv, prototype);
|
||||
KTX_error_code result = KTX_SUCCESS;
|
||||
|
||||
assert(This->supercompressionScheme == KTX_SS_BASIS_LZ);
|
||||
|
||||
uint8_t* bgd = priv._supercompressionGlobalData;
|
||||
ktxBasisLzGlobalHeader& bgdh = *reinterpret_cast<ktxBasisLzGlobalHeader*>(bgd);
|
||||
if (!(bgdh.endpointsByteLength && bgdh.selectorsByteLength && bgdh.tablesByteLength)) {
|
||||
debug_printf("ktxTexture_TranscodeBasis: missing endpoints, selectors or tables");
|
||||
return KTX_FILE_DATA_ERROR;
|
||||
}
|
||||
|
||||
// Compute some helpful numbers.
|
||||
//
|
||||
// firstImages contains the indices of the first images for each level to
|
||||
// ease finding the correct slice description when iterating from smallest
|
||||
// level to largest or when randomly accessing them (t.b.c). The last array
|
||||
// entry contains the total number of images, for calculating the offsets
|
||||
// of the endpoints, etc.
|
||||
uint32_t* firstImages = new uint32_t[This->numLevels+1];
|
||||
|
||||
// Temporary invariant value
|
||||
uint32_t layersFaces = This->numLayers * This->numFaces;
|
||||
firstImages[0] = 0;
|
||||
for (uint32_t level = 1; level <= This->numLevels; level++) {
|
||||
// NOTA BENE: numFaces * depth is only reasonable because they can't
|
||||
// both be > 1. I.e there are no 3d cubemaps.
|
||||
firstImages[level] = firstImages[level - 1]
|
||||
+ layersFaces * MAX(This->baseDepth >> (level - 1), 1);
|
||||
}
|
||||
uint32_t& imageCount = firstImages[This->numLevels];
|
||||
|
||||
if (BGD_TABLES_ADDR(0, bgdh, imageCount) + bgdh.tablesByteLength > priv._sgdByteLength) {
|
||||
// Compiler will not allow `goto cleanup;` because "jump bypasses variable initialization."
|
||||
// The static initializations below this and before the loop are presumably the issue
|
||||
// as the compiler is,presumably, inserting code to destruct those at the end of the
|
||||
// function.
|
||||
delete[] firstImages;
|
||||
return KTX_FILE_DATA_ERROR;
|
||||
}
|
||||
// FIXME: Do more validation.
|
||||
|
||||
// Prepare low-level transcoder for transcoding slices.
|
||||
basist::basisu_lowlevel_etc1s_transcoder bit;
|
||||
|
||||
// basisu_transcoder_state is used to find the previous frame when
|
||||
// decoding a video P-Frame. It tracks the previous frame for each mip
|
||||
// level. For cube map array textures we need to find the previous frame
|
||||
// for each face so we a state per face. Although providing this is only
|
||||
// needed for video, it is easier to always pass our own.
|
||||
std::vector<basisu_transcoder_state> xcoderStates;
|
||||
xcoderStates.resize(This->isVideo ? This->numFaces : 1);
|
||||
|
||||
bit.decode_palettes(bgdh.endpointCount, BGD_ENDPOINTS_ADDR(bgd, imageCount),
|
||||
bgdh.endpointsByteLength,
|
||||
bgdh.selectorCount, BGD_SELECTORS_ADDR(bgd, bgdh, imageCount),
|
||||
bgdh.selectorsByteLength);
|
||||
|
||||
bit.decode_tables(BGD_TABLES_ADDR(bgd, bgdh, imageCount),
|
||||
bgdh.tablesByteLength);
|
||||
|
||||
// Find matching VkFormat and calculate output sizes.
|
||||
|
||||
const bool isVideo = This->isVideo;
|
||||
|
||||
ktx_uint8_t* pXcodedData = prototype->pData;
|
||||
// Inconveniently, the output buffer size parameter of transcode_image
|
||||
// has to be in pixels for uncompressed output and in blocks for
|
||||
// compressed output. The only reason for humouring the API is so
|
||||
// its buffer size tests provide a real check. An alternative is to
|
||||
// always provide the size in bytes which will always pass.
|
||||
ktx_uint32_t outputBlockByteLength
|
||||
= prototype->_protected->_formatSize.blockSizeInBits / 8;
|
||||
ktx_size_t xcodedDataLength
|
||||
= prototype->dataSize / outputBlockByteLength;
|
||||
ktxLevelIndexEntry* protoLevelIndex;
|
||||
uint64_t levelOffsetWrite;
|
||||
const ktxBasisLzEtc1sImageDesc* imageDescs = BGD_ETC1S_IMAGE_DESCS(bgd);
|
||||
|
||||
// Finally we're ready to transcode the slices.
|
||||
|
||||
// FIXME: Iframe flag needs to be queryable by the application. In Basis
|
||||
// the app can query file_info and image_info from the transcoder which
|
||||
// returns a structure with lots of info about the image.
|
||||
|
||||
protoLevelIndex = protoPriv._levelIndex;
|
||||
levelOffsetWrite = 0;
|
||||
for (int32_t level = This->numLevels - 1; level >= 0; level--) {
|
||||
uint64_t levelOffset = ktxTexture2_levelDataOffset(This, level);
|
||||
uint64_t writeOffset = levelOffsetWrite;
|
||||
uint64_t writeOffsetBlocks = levelOffsetWrite / outputBlockByteLength;
|
||||
uint32_t levelWidth = MAX(1, This->baseWidth >> level);
|
||||
uint32_t levelHeight = MAX(1, This->baseHeight >> level);
|
||||
// ETC1S texel block dimensions
|
||||
const uint32_t bw = 4, bh = 4;
|
||||
uint32_t levelBlocksX = (levelWidth + (bw - 1)) / bw;
|
||||
uint32_t levelBlocksY = (levelHeight + (bh - 1)) / bh;
|
||||
uint32_t depth = MAX(1, This->baseDepth >> level);
|
||||
//uint32_t faceSlices = This->numFaces == 1 ? depth : This->numFaces;
|
||||
uint32_t faceSlices = This->numFaces * depth;
|
||||
uint32_t numImages = This->numLayers * faceSlices;
|
||||
uint32_t image = firstImages[level];
|
||||
uint32_t endImage = image + numImages;
|
||||
ktx_size_t levelImageSizeOut, levelSizeOut;
|
||||
uint32_t stateIndex = 0;
|
||||
|
||||
levelSizeOut = 0;
|
||||
// FIXME: Figure out a way to get the size out of the transcoder.
|
||||
levelImageSizeOut = ktxTexture2_GetImageSize(prototype, level);
|
||||
for (; image < endImage; image++) {
|
||||
const ktxBasisLzEtc1sImageDesc& imageDesc = imageDescs[image];
|
||||
|
||||
basisu_transcoder_state& xcoderState = xcoderStates[stateIndex];
|
||||
// We have face0 [face1 ...] within each layer. Use `stateIndex`
|
||||
// rather than a double loop of layers and faceSlices as this
|
||||
// works for 3d texture and non-array cube maps as well as
|
||||
// cube map arrays without special casing.
|
||||
if (++stateIndex == xcoderStates.size())
|
||||
stateIndex = 0;
|
||||
|
||||
if (alphaContent != eNone)
|
||||
{
|
||||
// The slice descriptions should have alpha information.
|
||||
if (imageDesc.alphaSliceByteOffset == 0
|
||||
|| imageDesc.alphaSliceByteLength == 0)
|
||||
return KTX_FILE_DATA_ERROR;
|
||||
}
|
||||
|
||||
bool status;
|
||||
status = bit.transcode_image(
|
||||
(transcoder_texture_format)outputFormat,
|
||||
pXcodedData + writeOffset,
|
||||
(uint32_t)(xcodedDataLength - writeOffsetBlocks),
|
||||
This->pData,
|
||||
(uint32_t)This->dataSize,
|
||||
levelBlocksX,
|
||||
levelBlocksY,
|
||||
levelWidth,
|
||||
levelHeight,
|
||||
level,
|
||||
(uint32_t)(levelOffset + imageDesc.rgbSliceByteOffset),
|
||||
imageDesc.rgbSliceByteLength,
|
||||
(uint32_t)(levelOffset + imageDesc.alphaSliceByteOffset),
|
||||
imageDesc.alphaSliceByteLength,
|
||||
transcodeFlags,
|
||||
alphaContent != eNone,
|
||||
isVideo,
|
||||
// Our P-Frame flag is in the same bit as
|
||||
// cSliceDescFlagsFrameIsIFrame. We have to
|
||||
// invert it to make it an I-Frame flag.
|
||||
//
|
||||
// API currently doesn't have any way to pass
|
||||
// the I-Frame flag.
|
||||
//imageDesc.imageFlags ^ cSliceDescFlagsFrameIsIFrame,
|
||||
0, // output_row_pitch_in_blocks_or_pixels
|
||||
&xcoderState,
|
||||
0 // output_rows_in_pixels
|
||||
);
|
||||
if (!status) {
|
||||
result = KTX_TRANSCODE_FAILED;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
writeOffset += levelImageSizeOut;
|
||||
levelSizeOut += levelImageSizeOut;
|
||||
} // end images loop
|
||||
protoLevelIndex[level].byteOffset = levelOffsetWrite;
|
||||
protoLevelIndex[level].byteLength = levelSizeOut;
|
||||
protoLevelIndex[level].uncompressedByteLength = levelSizeOut;
|
||||
levelOffsetWrite += levelSizeOut;
|
||||
assert(levelOffsetWrite == writeOffset);
|
||||
// In case of transcoding to uncompressed.
|
||||
levelOffsetWrite = _KTX_PADN(protoPriv._requiredLevelAlignment,
|
||||
levelOffsetWrite);
|
||||
} // level loop
|
||||
|
||||
result = KTX_SUCCESS;
|
||||
|
||||
cleanup:
|
||||
delete[] firstImages;
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
KTX_error_code
|
||||
ktxTexture2_transcodeUastc(ktxTexture2* This,
|
||||
alpha_content_e alphaContent,
|
||||
ktxTexture2* prototype,
|
||||
ktx_transcode_fmt_e outputFormat,
|
||||
ktx_transcode_flags transcodeFlags)
|
||||
{
|
||||
assert(This->supercompressionScheme != KTX_SS_BASIS_LZ);
|
||||
|
||||
ktx_uint8_t* pXcodedData = prototype->pData;
|
||||
ktx_uint32_t outputBlockByteLength
|
||||
= prototype->_protected->_formatSize.blockSizeInBits / 8;
|
||||
ktx_size_t xcodedDataLength
|
||||
= prototype->dataSize / outputBlockByteLength;
|
||||
DECLARE_PRIVATE(protoPriv, prototype);
|
||||
ktxLevelIndexEntry* protoLevelIndex = protoPriv._levelIndex;
|
||||
ktx_size_t levelOffsetWrite = 0;
|
||||
|
||||
basisu_lowlevel_uastc_ldr_4x4_transcoder uit;
|
||||
// See comment on same declaration in transcodeEtc1s.
|
||||
std::vector<basisu_transcoder_state> xcoderStates;
|
||||
xcoderStates.resize(This->isVideo ? This->numFaces : 1);
|
||||
|
||||
for (ktx_int32_t level = This->numLevels - 1; level >= 0; level--)
|
||||
{
|
||||
ktx_uint32_t depth;
|
||||
uint64_t writeOffset = levelOffsetWrite;
|
||||
uint64_t writeOffsetBlocks = levelOffsetWrite / outputBlockByteLength;
|
||||
ktx_size_t levelImageSizeIn, levelImageOffsetIn;
|
||||
ktx_size_t levelImageSizeOut, levelSizeOut;
|
||||
ktx_uint32_t levelImageCount;
|
||||
uint32_t levelWidth = MAX(1, This->baseWidth >> level);
|
||||
uint32_t levelHeight = MAX(1, This->baseHeight >> level);
|
||||
// UASTC texel block dimensions
|
||||
const uint32_t bw = 4, bh = 4;
|
||||
uint32_t levelBlocksX = (levelWidth + (bw - 1)) / bw;
|
||||
uint32_t levelBlocksY = (levelHeight + (bh - 1)) / bh;
|
||||
uint32_t stateIndex = 0;
|
||||
|
||||
depth = MAX(1, This->baseDepth >> level);
|
||||
|
||||
levelImageCount = This->numLayers * This->numFaces * depth;
|
||||
levelImageSizeIn = ktxTexture_calcImageSize(ktxTexture(This), level,
|
||||
KTX_FORMAT_VERSION_TWO);
|
||||
levelImageSizeOut = ktxTexture_calcImageSize(ktxTexture(prototype),
|
||||
level,
|
||||
KTX_FORMAT_VERSION_TWO);
|
||||
|
||||
levelImageOffsetIn = ktxTexture2_levelDataOffset(This, level);
|
||||
levelSizeOut = 0;
|
||||
bool status;
|
||||
for (uint32_t image = 0; image < levelImageCount; image++) {
|
||||
basisu_transcoder_state& xcoderState = xcoderStates[stateIndex];
|
||||
// See comment before same lines in transcodeEtc1s.
|
||||
if (++stateIndex == xcoderStates.size())
|
||||
stateIndex = 0;
|
||||
|
||||
status = uit.transcode_image(
|
||||
(transcoder_texture_format)outputFormat,
|
||||
pXcodedData + writeOffset,
|
||||
(uint32_t)(xcodedDataLength - writeOffsetBlocks),
|
||||
This->pData,
|
||||
(uint32_t)This->dataSize,
|
||||
levelBlocksX,
|
||||
levelBlocksY,
|
||||
levelWidth,
|
||||
levelHeight,
|
||||
level,
|
||||
(uint32_t)levelImageOffsetIn,
|
||||
(uint32_t)levelImageSizeIn,
|
||||
transcodeFlags,
|
||||
alphaContent != eNone,
|
||||
This->isVideo, // is_video
|
||||
//imageDesc.imageFlags ^ cSliceDescFlagsFrameIsIFrame,
|
||||
0, // output_row_pitch_in_blocks_or_pixels
|
||||
&xcoderState, // pState
|
||||
0, // output_rows_in_pixels,
|
||||
-1, // channel0
|
||||
-1 // channel1
|
||||
);
|
||||
if (!status)
|
||||
return KTX_TRANSCODE_FAILED;
|
||||
writeOffset += levelImageSizeOut;
|
||||
levelSizeOut += levelImageSizeOut;
|
||||
levelImageOffsetIn += levelImageSizeIn;
|
||||
}
|
||||
protoLevelIndex[level].byteOffset = levelOffsetWrite;
|
||||
// writeOffset will be equal to total size of the images in the level.
|
||||
protoLevelIndex[level].byteLength = levelSizeOut;
|
||||
protoLevelIndex[level].uncompressedByteLength = levelSizeOut;
|
||||
levelOffsetWrite += levelSizeOut;
|
||||
}
|
||||
// In case of transcoding to uncompressed.
|
||||
levelOffsetWrite = _KTX_PADN(protoPriv._requiredLevelAlignment,
|
||||
levelOffsetWrite);
|
||||
return KTX_SUCCESS;
|
||||
}
|
299
thirdparty/libktx/lib/checkheader.c
vendored
Normal file
299
thirdparty/libktx/lib/checkheader.c
vendored
Normal file
@@ -0,0 +1,299 @@
|
||||
/* -*- tab-width: 4; -*- */
|
||||
/* vi: set sw=2 ts=4 expandtab: */
|
||||
|
||||
/* $Id$ */
|
||||
|
||||
/*
|
||||
* Copyright 2010-2020 The Khronos Group Inc.
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
/**
|
||||
* @internal
|
||||
* @file
|
||||
* @~English
|
||||
*
|
||||
* @brief Function to verify a KTX file header
|
||||
*
|
||||
* @author Mark Callow, HI Corporation
|
||||
*/
|
||||
|
||||
/*
|
||||
* Author: Georg Kolling, Imagination Technology with modifications
|
||||
* by Mark Callow, HI Corporation.
|
||||
*/
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "ktx.h"
|
||||
#include "ktxint.h"
|
||||
#include "vkformat_enum.h"
|
||||
|
||||
bool isProhibitedFormat(VkFormat format);
|
||||
bool isValidFormat(VkFormat format);
|
||||
|
||||
/**
|
||||
* @internal
|
||||
* @~English
|
||||
* @brief Check a KTX file header.
|
||||
*
|
||||
* As well as checking that the header identifies a KTX file, the function
|
||||
* sanity checks the values and returns information about the texture in a
|
||||
* struct KTX_supplementary_info.
|
||||
*
|
||||
* @param pHeader pointer to the KTX header to check
|
||||
* @param pSuppInfo pointer to a KTX_supplementary_info structure in which to
|
||||
* return information about the texture.
|
||||
*
|
||||
* @author Georg Kolling, Imagination Technology
|
||||
* @author Mark Callow, HI Corporation
|
||||
*/
|
||||
|
||||
KTX_error_code ktxCheckHeader1_(KTX_header* pHeader,
|
||||
KTX_supplemental_info* pSuppInfo)
|
||||
{
|
||||
ktx_uint8_t identifier_reference[12] = KTX_IDENTIFIER_REF;
|
||||
ktx_uint32_t max_dim;
|
||||
|
||||
assert(pHeader != NULL && pSuppInfo != NULL);
|
||||
|
||||
/* Compare identifier, is this a KTX file? */
|
||||
if (memcmp(pHeader->identifier, identifier_reference, 12) != 0)
|
||||
{
|
||||
return KTX_UNKNOWN_FILE_FORMAT;
|
||||
}
|
||||
|
||||
if (pHeader->endianness == KTX_ENDIAN_REF_REV)
|
||||
{
|
||||
/* Convert endianness of pHeader fields. */
|
||||
_ktxSwapEndian32(&pHeader->glType, 12);
|
||||
|
||||
if (pHeader->glTypeSize != 1 &&
|
||||
pHeader->glTypeSize != 2 &&
|
||||
pHeader->glTypeSize != 4)
|
||||
{
|
||||
/* Only 8-, 16-, and 32-bit types supported so far. */
|
||||
return KTX_FILE_DATA_ERROR;
|
||||
}
|
||||
}
|
||||
else if (pHeader->endianness != KTX_ENDIAN_REF)
|
||||
{
|
||||
return KTX_FILE_DATA_ERROR;
|
||||
}
|
||||
|
||||
/* Check glType and glFormat */
|
||||
pSuppInfo->compressed = 0;
|
||||
if (pHeader->glType == 0 || pHeader->glFormat == 0)
|
||||
{
|
||||
if (pHeader->glType + pHeader->glFormat != 0)
|
||||
{
|
||||
/* either both or none of glType, glFormat must be zero */
|
||||
return KTX_FILE_DATA_ERROR;
|
||||
}
|
||||
pSuppInfo->compressed = 1;
|
||||
}
|
||||
|
||||
if (pHeader->glFormat == pHeader->glInternalformat) {
|
||||
// glInternalFormat is either unsized (which is no longer and should
|
||||
// never have been supported by libktx) or glFormat is sized.
|
||||
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 GL extension for 3D array textures. */
|
||||
if ((pHeader->pixelWidth == 0) ||
|
||||
(pHeader->pixelDepth > 0 && pHeader->pixelHeight == 0))
|
||||
{
|
||||
/* texture must have width */
|
||||
/* texture must have height if it has depth */
|
||||
return KTX_FILE_DATA_ERROR;
|
||||
}
|
||||
|
||||
|
||||
if (pHeader->pixelDepth > 0)
|
||||
{
|
||||
if (pHeader->numberOfArrayElements > 0)
|
||||
{
|
||||
/* No 3D array textures yet. */
|
||||
return KTX_UNSUPPORTED_FEATURE;
|
||||
}
|
||||
pSuppInfo->textureDimension = 3;
|
||||
}
|
||||
else if (pHeader->pixelHeight > 0)
|
||||
{
|
||||
pSuppInfo->textureDimension = 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
pSuppInfo->textureDimension = 1;
|
||||
}
|
||||
|
||||
if (pHeader->numberOfFaces == 6)
|
||||
{
|
||||
if (pSuppInfo->textureDimension != 2)
|
||||
{
|
||||
/* cube map needs 2D faces */
|
||||
return KTX_FILE_DATA_ERROR;
|
||||
}
|
||||
}
|
||||
else if (pHeader->numberOfFaces != 1)
|
||||
{
|
||||
/* numberOfFaces must be either 1 or 6 */
|
||||
return KTX_FILE_DATA_ERROR;
|
||||
}
|
||||
|
||||
/* Check number of mipmap levels */
|
||||
if (pHeader->numberOfMipLevels == 0)
|
||||
{
|
||||
pSuppInfo->generateMipmaps = 1;
|
||||
pHeader->numberOfMipLevels = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
pSuppInfo->generateMipmaps = 0;
|
||||
}
|
||||
|
||||
/* 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->numberOfMipLevels - 1)))
|
||||
{
|
||||
/* Can't have more mip levels than 1 + log2(max(width, height, depth)) */
|
||||
return KTX_FILE_DATA_ERROR;
|
||||
}
|
||||
|
||||
return KTX_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
* @~English
|
||||
* @brief Check a KTX2 file header.
|
||||
*
|
||||
* As well as checking that the header identifies a KTX 2 file, the function
|
||||
* sanity checks the values and returns information about the texture in a
|
||||
* struct KTX_supplementary_info.
|
||||
*
|
||||
* @param pHeader pointer to the KTX header to check
|
||||
* @param pSuppInfo pointer to a KTX_supplementary_info structure in which to
|
||||
* return information about the texture.
|
||||
*
|
||||
* @author Mark Callow, HI Corporation
|
||||
*/
|
||||
KTX_error_code ktxCheckHeader2_(KTX_header2* pHeader,
|
||||
KTX_supplemental_info* pSuppInfo)
|
||||
{
|
||||
// supp info is compressed, generateMipmaps and num dimensions. Don't need
|
||||
// compressed as formatSize gives us that. I think the other 2 aren't needed.
|
||||
ktx_uint8_t identifier_reference[12] = KTX2_IDENTIFIER_REF;
|
||||
|
||||
assert(pHeader != NULL && pSuppInfo != NULL);
|
||||
ktx_uint32_t max_dim;
|
||||
|
||||
/* Compare identifier, is this a KTX file? */
|
||||
if (memcmp(pHeader->identifier, identifier_reference, 12) != 0)
|
||||
{
|
||||
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. */
|
||||
if ((pHeader->pixelWidth == 0) ||
|
||||
(pHeader->pixelDepth > 0 && pHeader->pixelHeight == 0))
|
||||
{
|
||||
/* texture must have width */
|
||||
/* texture must have height if it has depth */
|
||||
return KTX_FILE_DATA_ERROR;
|
||||
}
|
||||
|
||||
if (pHeader->pixelDepth > 0)
|
||||
{
|
||||
if (pHeader->layerCount > 0)
|
||||
{
|
||||
/* No 3D array textures yet. */
|
||||
return KTX_UNSUPPORTED_FEATURE;
|
||||
}
|
||||
pSuppInfo->textureDimension = 3;
|
||||
}
|
||||
else if (pHeader->pixelHeight > 0)
|
||||
{
|
||||
pSuppInfo->textureDimension = 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
pSuppInfo->textureDimension = 1;
|
||||
}
|
||||
|
||||
if (pHeader->faceCount == 6)
|
||||
{
|
||||
if (pSuppInfo->textureDimension != 2)
|
||||
{
|
||||
/* 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)
|
||||
{
|
||||
/* numberOfFaces must be either 1 or 6 */
|
||||
return KTX_FILE_DATA_ERROR;
|
||||
}
|
||||
|
||||
// Check number of mipmap levels
|
||||
if (pHeader->levelCount == 0)
|
||||
{
|
||||
pSuppInfo->generateMipmaps = 1;
|
||||
pHeader->levelCount = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
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)))
|
||||
{
|
||||
// Can't have more mip levels than 1 + log2(max(width, height, depth))
|
||||
return KTX_FILE_DATA_ERROR;
|
||||
}
|
||||
|
||||
return KTX_SUCCESS;
|
||||
|
||||
}
|
395
thirdparty/libktx/lib/filestream.c
vendored
Normal file
395
thirdparty/libktx/lib/filestream.c
vendored
Normal file
@@ -0,0 +1,395 @@
|
||||
/* -*- tab-width: 4; -*- */
|
||||
/* vi: set sw=2 ts=4 expandtab: */
|
||||
|
||||
/*
|
||||
* Copyright 2010-2020 The Khronos Group Inc.
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file
|
||||
* @~English
|
||||
*
|
||||
* @brief Implementation of ktxStream for FILE.
|
||||
*
|
||||
* @author Maksim Kolesin, Under Development
|
||||
* @author Georg Kolling, Imagination Technology
|
||||
* @author Mark Callow, HI Corporation
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <inttypes.h>
|
||||
#include <string.h>
|
||||
/* I need these on Linux. Why? */
|
||||
#define __USE_LARGEFILE 1 // For declaration of ftello, etc.
|
||||
#define __USE_POSIX 1 // For declaration of fileno.
|
||||
#define _POSIX_SOURCE 1 // For both the above in Emscripten.
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/types.h> // For stat.h on Windows
|
||||
#define __USE_MISC 1 // For declaration of S_IF...
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include "ktx.h"
|
||||
#include "ktxint.h"
|
||||
#include "filestream.h"
|
||||
|
||||
// Gotta love Windows :-(
|
||||
#if defined(_MSC_VER)
|
||||
#if defined(_WIN64)
|
||||
#define ftello _ftelli64
|
||||
#define fseeko _fseeki64
|
||||
#else
|
||||
#define ftello ftell
|
||||
#define fseeko fseek
|
||||
#endif
|
||||
#define fileno _fileno
|
||||
#define fstat _fstat
|
||||
#define stat _stat
|
||||
#define S_IFIFO _S_IFIFO
|
||||
#define S_IFSOCK 0xC000
|
||||
typedef unsigned short mode_t;
|
||||
#endif
|
||||
|
||||
#if defined(__MINGW32__)
|
||||
#define S_IFSOCK 0xC000
|
||||
#endif
|
||||
|
||||
#define KTX_FILE_STREAM_MAX (1 << (sizeof(ktx_off_t) - 1) - 1)
|
||||
|
||||
/**
|
||||
* @~English
|
||||
* @brief Read bytes from a ktxFileStream.
|
||||
*
|
||||
* @param [in] str pointer to the ktxStream from which to read.
|
||||
* @param [out] dst pointer to a block of memory with a size
|
||||
* of at least @p size bytes, converted to a void*.
|
||||
* @param [in,out] count pointer to total count of bytes to be read.
|
||||
* On completion set to number of bytes read.
|
||||
*
|
||||
* @return KTX_SUCCESS on success, other KTX_* enum values on error.
|
||||
*
|
||||
* @exception KTX_INVALID_VALUE @p dst is @c NULL or @p src is @c NULL.
|
||||
* @exception KTX_FILE_READ_ERROR an error occurred while reading the file.
|
||||
* @exception KTX_FILE_UNEXPECTED_EOF not enough data to satisfy the request.
|
||||
*/
|
||||
static
|
||||
KTX_error_code ktxFileStream_read(ktxStream* str, void* dst, const ktx_size_t count)
|
||||
{
|
||||
ktx_size_t nread;
|
||||
|
||||
if (!str || !dst)
|
||||
return KTX_INVALID_VALUE;
|
||||
|
||||
assert(str->type == eStreamTypeFile);
|
||||
|
||||
if ((nread = fread(dst, 1, count, str->data.file)) != count) {
|
||||
if (feof(str->data.file)) {
|
||||
return KTX_FILE_UNEXPECTED_EOF;
|
||||
} else {
|
||||
return KTX_FILE_READ_ERROR;
|
||||
}
|
||||
}
|
||||
str->readpos += count;
|
||||
|
||||
return KTX_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* @~English
|
||||
* @brief Skip bytes in a ktxFileStream.
|
||||
*
|
||||
* @param [in] str pointer to a ktxStream object.
|
||||
* @param [in] count number of bytes to be skipped.
|
||||
*
|
||||
* In order to support applications reading from stdin, read characters
|
||||
* rather than using seek functions.
|
||||
*
|
||||
* @return KTX_SUCCESS on success, other KTX_* enum values on error.
|
||||
*
|
||||
* @exception KTX_INVALID_VALUE @p str is @c NULL or @p count is less than zero.
|
||||
* @exception KTX_INVALID_OPERATION skipping @p count bytes would go beyond EOF.
|
||||
* @exception KTX_FILE_READ_ERROR an error occurred while reading the file.
|
||||
* @exception KTX_FILE_UNEXPECTED_EOF not enough data to satisfy the request.
|
||||
* @p count is set to the number of bytes
|
||||
* skipped.
|
||||
*/
|
||||
static
|
||||
KTX_error_code ktxFileStream_skip(ktxStream* str, const ktx_size_t count)
|
||||
{
|
||||
if (!str)
|
||||
return KTX_INVALID_VALUE;
|
||||
|
||||
assert(str->type == eStreamTypeFile);
|
||||
|
||||
for (ktx_uint32_t i = 0; i < count; i++) {
|
||||
int ret = getc(str->data.file);
|
||||
if (ret == EOF) {
|
||||
if (feof(str->data.file)) {
|
||||
return KTX_FILE_UNEXPECTED_EOF;
|
||||
} else {
|
||||
return KTX_FILE_READ_ERROR;
|
||||
}
|
||||
}
|
||||
}
|
||||
str->readpos += count;
|
||||
|
||||
return KTX_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* @~English
|
||||
* @brief Write bytes to a ktxFileStream.
|
||||
*
|
||||
* @param [in] str pointer to the ktxStream that is the destination of the
|
||||
* write.
|
||||
* @param [in] src pointer to the array of elements to be written,
|
||||
* converted to a const void*.
|
||||
* @param [in] size size in bytes of each element to be written.
|
||||
* @param [in] count number of elements, each one with a @p size of size
|
||||
* bytes.
|
||||
*
|
||||
* @return KTX_SUCCESS on success, other KTX_* enum values on error.
|
||||
*
|
||||
* @exception KTX_INVALID_VALUE @p str is @c NULL or @p src is @c NULL.
|
||||
* @exception KTX_FILE_OVERFLOW the requested write would caused the file to
|
||||
* exceed the maximum supported file size.
|
||||
* @exception KTX_FILE_WRITE_ERROR a system error occurred while writing the
|
||||
* file.
|
||||
*/
|
||||
static
|
||||
KTX_error_code ktxFileStream_write(ktxStream* str, const void *src,
|
||||
const ktx_size_t size,
|
||||
const ktx_size_t count)
|
||||
{
|
||||
if (!str || !src)
|
||||
return KTX_INVALID_VALUE;
|
||||
|
||||
assert(str->type == eStreamTypeFile);
|
||||
|
||||
if (fwrite(src, size, count, str->data.file) != count) {
|
||||
if (errno == EFBIG || errno == EOVERFLOW)
|
||||
return KTX_FILE_OVERFLOW;
|
||||
else
|
||||
return KTX_FILE_WRITE_ERROR;
|
||||
}
|
||||
|
||||
return KTX_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* @~English
|
||||
* @brief Get the current read/write position in a ktxFileStream.
|
||||
*
|
||||
* @param [in] str pointer to the ktxStream to query.
|
||||
* @param [in,out] off pointer to variable to receive the offset value.
|
||||
*
|
||||
* @return KTX_SUCCESS on success, other KTX_* enum values on error.
|
||||
*
|
||||
* @exception KTX_FILE_ISPIPE file descriptor underlying stream is associated
|
||||
* with a pipe or FIFO so does not have a
|
||||
* file-position indicator.
|
||||
* @exception KTX_INVALID_VALUE @p str or @p pos is @c NULL.
|
||||
*/
|
||||
static
|
||||
KTX_error_code ktxFileStream_getpos(ktxStream* str, ktx_off_t* pos)
|
||||
{
|
||||
ktx_off_t ftellval;
|
||||
|
||||
if (!str || !pos)
|
||||
return KTX_INVALID_VALUE;
|
||||
|
||||
assert(str->type == eStreamTypeFile);
|
||||
|
||||
if (str->data.file == stdin) {
|
||||
*pos = str->readpos;
|
||||
} else {
|
||||
/* The cast quiets an Xcode warning when building for "Generic iOS Device".
|
||||
* I'm not sure why.
|
||||
*/
|
||||
ftellval = (ktx_off_t)ftello(str->data.file);
|
||||
if (ftellval < 0) {
|
||||
switch (errno) {
|
||||
case ESPIPE: return KTX_FILE_ISPIPE;
|
||||
case EOVERFLOW: return KTX_FILE_OVERFLOW;
|
||||
}
|
||||
}
|
||||
|
||||
*pos = ftellval;
|
||||
}
|
||||
|
||||
return KTX_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* @~English
|
||||
* @brief Set the current read/write position in a ktxFileStream.
|
||||
*
|
||||
* Offset of 0 is the start of the file. This function operates
|
||||
* like Linux > 3.1's @c lseek() when it is passed a @c whence
|
||||
* of @c SEEK_DATA as it returns an error if the seek would
|
||||
* go beyond the end of the file.
|
||||
*
|
||||
* @param [in] str pointer to the ktxStream whose r/w position is to be set.
|
||||
* @param [in] off pointer to the offset value to set.
|
||||
*
|
||||
* @return KTX_SUCCESS on success, other KTX_* enum values on error.
|
||||
*
|
||||
* Throws the same exceptions as ktxFileStream_getsize() for the reasons given
|
||||
* there plus the following:
|
||||
*
|
||||
* @exception KTX_INVALID_VALUE @p str is @c NULL.
|
||||
* @exception KTX_INVALID_OPERATION @p pos is > the size of the file or an
|
||||
* fseek error occurred.
|
||||
*/
|
||||
static
|
||||
KTX_error_code ktxFileStream_setpos(ktxStream* str, ktx_off_t pos)
|
||||
{
|
||||
ktx_size_t fileSize;
|
||||
KTX_error_code result;
|
||||
|
||||
if (!str)
|
||||
return KTX_INVALID_VALUE;
|
||||
|
||||
assert(str->type == eStreamTypeFile);
|
||||
|
||||
if (str->data.file == stdin) {
|
||||
if (pos > str->readpos)
|
||||
return str->skip(str, pos - str->readpos);
|
||||
else
|
||||
return KTX_FILE_ISPIPE;
|
||||
}
|
||||
|
||||
result = str->getsize(str, &fileSize);
|
||||
|
||||
if (result != KTX_SUCCESS) {
|
||||
// Device is likely not seekable.
|
||||
return result;
|
||||
}
|
||||
|
||||
if (pos > (ktx_off_t)fileSize)
|
||||
return KTX_INVALID_OPERATION;
|
||||
|
||||
if (fseeko(str->data.file, pos, SEEK_SET) < 0)
|
||||
return KTX_FILE_SEEK_ERROR;
|
||||
else
|
||||
return KTX_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* @~English
|
||||
* @brief Get the size of a ktxFileStream in bytes.
|
||||
*
|
||||
* @param [in] str pointer to the ktxStream whose size is to be queried.
|
||||
* @param [in,out] size pointer to a variable in which size will be written.
|
||||
*
|
||||
* @return KTX_SUCCESS on success, other KTX_* enum values on error.
|
||||
*
|
||||
* @exception KTX_FILE_OVERFLOW size is too large to be returned in a
|
||||
* @c ktx_size_t.
|
||||
* @exception KTX_FILE_ISPIPE file descriptor underlying stream is associated
|
||||
* with a pipe or FIFO so does not have a
|
||||
* file-position indicator.
|
||||
* @exception KTX_FILE_READ_ERROR a system error occurred while getting the
|
||||
* size.
|
||||
* @exception KTX_INVALID_VALUE @p str or @p size is @c NULL.
|
||||
* @exception KTX_INVALID_OPERATION stream is a tty.
|
||||
*/
|
||||
static
|
||||
KTX_error_code ktxFileStream_getsize(ktxStream* str, ktx_size_t* size)
|
||||
{
|
||||
struct stat statbuf;
|
||||
int statret;
|
||||
|
||||
if (!str || !size)
|
||||
return KTX_INVALID_VALUE;
|
||||
|
||||
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.
|
||||
#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)
|
||||
(void)fflush(str->data.file);
|
||||
#else
|
||||
(void)fflush(str->data.file);
|
||||
#endif
|
||||
statret = fstat(fileno(str->data.file), &statbuf);
|
||||
if (statret < 0) {
|
||||
switch (errno) {
|
||||
case EOVERFLOW: return KTX_FILE_OVERFLOW;
|
||||
case EIO:
|
||||
default:
|
||||
return KTX_FILE_READ_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
mode_t ftype = statbuf.st_mode & S_IFMT;
|
||||
if (ftype == S_IFIFO || ftype == S_IFSOCK)
|
||||
return KTX_FILE_ISPIPE;
|
||||
|
||||
if (statbuf.st_mode & S_IFCHR)
|
||||
return KTX_INVALID_OPERATION;
|
||||
|
||||
*size = (ktx_size_t)statbuf.st_size; /* See _getpos for why this cast. */
|
||||
|
||||
return KTX_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* @~English
|
||||
* @brief Initialize a ktxFileStream.
|
||||
*
|
||||
* @param [in] str pointer to the ktxStream to initialize.
|
||||
* @param [in] file pointer to the underlying FILE object.
|
||||
* @param [in] closeFileOnDestruct if not false, stdio file pointer will be closed when ktxStream
|
||||
* is destructed.
|
||||
*
|
||||
* @return KTX_SUCCESS on success, KTX_INVALID_VALUE on error.
|
||||
*
|
||||
* @exception KTX_INVALID_VALUE @p stream is @c NULL or @p file is @c NULL.
|
||||
*/
|
||||
KTX_error_code ktxFileStream_construct(ktxStream* str, FILE* file,
|
||||
ktx_bool_t closeFileOnDestruct)
|
||||
{
|
||||
if (!str || !file)
|
||||
return KTX_INVALID_VALUE;
|
||||
|
||||
str->data.file = file;
|
||||
str->readpos = 0;
|
||||
str->type = eStreamTypeFile;
|
||||
str->read = ktxFileStream_read;
|
||||
str->skip = ktxFileStream_skip;
|
||||
str->write = ktxFileStream_write;
|
||||
str->getpos = ktxFileStream_getpos;
|
||||
str->setpos = ktxFileStream_setpos;
|
||||
str->getsize = ktxFileStream_getsize;
|
||||
str->destruct = ktxFileStream_destruct;
|
||||
str->closeOnDestruct = closeFileOnDestruct;
|
||||
|
||||
return KTX_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* @~English
|
||||
* @brief Destruct the stream, potentially closing the underlying FILE.
|
||||
*
|
||||
* This only closes the underyling FILE if the @c closeOnDestruct parameter to
|
||||
* ktxFileStream_construct() was not @c KTX_FALSE.
|
||||
*
|
||||
* @param [in] str pointer to the ktxStream whose FILE is to potentially
|
||||
* be closed.
|
||||
*/
|
||||
void
|
||||
ktxFileStream_destruct(ktxStream* str)
|
||||
{
|
||||
assert(str && str->type == eStreamTypeFile);
|
||||
|
||||
if (str->closeOnDestruct)
|
||||
fclose(str->data.file);
|
||||
str->data.file = 0;
|
||||
}
|
27
thirdparty/libktx/lib/filestream.h
vendored
Normal file
27
thirdparty/libktx/lib/filestream.h
vendored
Normal file
@@ -0,0 +1,27 @@
|
||||
/* -*- tab-width: 4; -*- */
|
||||
/* vi: set sw=2 ts=4 expandtab: */
|
||||
|
||||
/*
|
||||
* Copyright 2010-2020 The Khronos Group Inc.
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
/*
|
||||
* Author: Maksim Kolesin from original code
|
||||
* by Mark Callow and Georg Kolling
|
||||
*/
|
||||
|
||||
#ifndef FILESTREAM_H
|
||||
#define FILESTREAM_H
|
||||
|
||||
#include "ktx.h"
|
||||
|
||||
/*
|
||||
* ktxFileInit: Initialize a ktxStream to a ktxFileStream with a FILE object
|
||||
*/
|
||||
KTX_error_code ktxFileStream_construct(ktxStream* str, FILE* file,
|
||||
ktx_bool_t closeFileOnDestruct);
|
||||
|
||||
void ktxFileStream_destruct(ktxStream* str);
|
||||
|
||||
#endif /* FILESTREAM_H */
|
59
thirdparty/libktx/lib/formatsize.h
vendored
Normal file
59
thirdparty/libktx/lib/formatsize.h
vendored
Normal file
@@ -0,0 +1,59 @@
|
||||
/* -*- tab-width: 4; -*- */
|
||||
/* vi: set sw=2 ts=4 expandtab: */
|
||||
|
||||
/*
|
||||
* Copyright 2019-2020 The Khronos Group Inc.
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
/**
|
||||
* @internal
|
||||
* @file
|
||||
* @~English
|
||||
*
|
||||
* @brief Struct for returning size information about an image format.
|
||||
*
|
||||
* @author Mark Callow, www.edgewise-consulting.com
|
||||
*/
|
||||
|
||||
#ifndef _FORMATSIZE_H_
|
||||
#define _FORMATSIZE_H_
|
||||
|
||||
#include "ktx.h"
|
||||
|
||||
typedef enum ktxFormatSizeFlagBits {
|
||||
KTX_FORMAT_SIZE_PACKED_BIT = 0x00000001,
|
||||
KTX_FORMAT_SIZE_COMPRESSED_BIT = 0x00000002,
|
||||
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;
|
||||
|
||||
/**
|
||||
* @brief Structure for holding size information for a texture format.
|
||||
*/
|
||||
typedef struct ktxFormatSize {
|
||||
ktxFormatSizeFlags flags;
|
||||
unsigned int paletteSizeInBits; // For KTX1.
|
||||
unsigned int blockSizeInBits;
|
||||
unsigned int blockWidth; // in texels
|
||||
unsigned int blockHeight; // in texels
|
||||
unsigned int blockDepth; // in texels
|
||||
unsigned int minBlocksX; // Minimum required number of blocks
|
||||
unsigned int minBlocksY;
|
||||
} ktxFormatSize;
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
bool ktxFormatSize_initFromDfd(ktxFormatSize* This, ktx_uint32_t* pDfd);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
#endif /* _FORMATSIZE_H_ */
|
2438
thirdparty/libktx/lib/gl_format.h
vendored
Normal file
2438
thirdparty/libktx/lib/gl_format.h
vendored
Normal file
File diff suppressed because it is too large
Load Diff
628
thirdparty/libktx/lib/hashlist.c
vendored
Normal file
628
thirdparty/libktx/lib/hashlist.c
vendored
Normal file
@@ -0,0 +1,628 @@
|
||||
/* -*- tab-width: 4; -*- */
|
||||
/* vi: set sw=2 ts=4 expandtab: */
|
||||
|
||||
/*
|
||||
* Copyright 2010-2020 The Khronos Group Inc.
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
/**
|
||||
* @internal
|
||||
* @file
|
||||
* @~English
|
||||
*
|
||||
* @brief Functions for creating and using a hash list of key-value
|
||||
* pairs.
|
||||
*
|
||||
* @author Mark Callow, HI Corporation
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
|
||||
// This is to avoid compile warnings. strlen is defined as returning
|
||||
// size_t and is used by the uthash macros. This avoids having to
|
||||
// make changes to uthash and a bunch of casts in this file. The
|
||||
// casts would be required because the key and value lengths in KTX
|
||||
// are specified as 4 byte quantities so we can't change _keyAndValue
|
||||
// below to use size_t.
|
||||
#define strlen(x) ((unsigned int)strlen(x))
|
||||
|
||||
#include "uthash.h"
|
||||
|
||||
#include "ktx.h"
|
||||
#include "ktxint.h"
|
||||
|
||||
|
||||
/**
|
||||
* @internal
|
||||
* @struct ktxKVListEntry
|
||||
* @brief Hash list entry structure
|
||||
*/
|
||||
typedef struct ktxKVListEntry {
|
||||
unsigned int keyLen; /*!< Length of the key */
|
||||
char* key; /*!< Pointer to key string */
|
||||
unsigned int valueLen; /*!< Length of the value */
|
||||
void* value; /*!< Pointer to the value */
|
||||
UT_hash_handle hh; /*!< handle used by UT hash */
|
||||
} ktxKVListEntry;
|
||||
|
||||
|
||||
/**
|
||||
* @memberof ktxHashList @public
|
||||
* @~English
|
||||
* @brief Construct an empty hash list for storing key-value pairs.
|
||||
*
|
||||
* @param [in] pHead pointer to the location to write the list head.
|
||||
*/
|
||||
void
|
||||
ktxHashList_Construct(ktxHashList* pHead)
|
||||
{
|
||||
*pHead = NULL;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @memberof ktxHashList @public
|
||||
* @~English
|
||||
* @brief Construct a hash list by copying another.
|
||||
*
|
||||
* @param [in] pHead pointer to head of the list.
|
||||
* @param [in] orig head of the original hash list.
|
||||
*/
|
||||
void
|
||||
ktxHashList_ConstructCopy(ktxHashList* pHead, ktxHashList orig)
|
||||
{
|
||||
ktxHashListEntry* entry = orig;
|
||||
*pHead = NULL;
|
||||
for (; entry != NULL; entry = ktxHashList_Next(entry)) {
|
||||
(void)ktxHashList_AddKVPair(pHead,
|
||||
entry->key, entry->valueLen, entry->value);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @memberof ktxHashList @public
|
||||
* @~English
|
||||
* @brief Destruct a hash list.
|
||||
*
|
||||
* All memory associated with the hash list's keys and values
|
||||
* is freed.
|
||||
*
|
||||
* @param [in] pHead pointer to the hash list to be destroyed.
|
||||
*/
|
||||
void
|
||||
ktxHashList_Destruct(ktxHashList* pHead)
|
||||
{
|
||||
ktxKVListEntry* kv;
|
||||
ktxKVListEntry* head = *pHead;
|
||||
|
||||
for(kv = head; kv != NULL;) {
|
||||
ktxKVListEntry* tmp = (ktxKVListEntry*)kv->hh.next;
|
||||
HASH_DELETE(hh, head, kv);
|
||||
free(kv);
|
||||
kv = tmp;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @memberof ktxHashList @public
|
||||
* @~English
|
||||
* @brief Create an empty hash list for storing key-value pairs.
|
||||
*
|
||||
* @param [in,out] ppHl address of a variable in which to set a pointer to
|
||||
* the newly created hash list.
|
||||
*
|
||||
* @return KTX_SUCCESS or one of the following error codes.
|
||||
* @exception KTX_OUT_OF_MEMORY if not enough memory.
|
||||
*/
|
||||
KTX_error_code
|
||||
ktxHashList_Create(ktxHashList** ppHl)
|
||||
{
|
||||
ktxHashList* hl = (ktxHashList*)malloc(sizeof (ktxKVListEntry*));
|
||||
if (hl == NULL)
|
||||
return KTX_OUT_OF_MEMORY;
|
||||
|
||||
ktxHashList_Construct(hl);
|
||||
*ppHl = hl;
|
||||
return KTX_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @memberof ktxHashList @public
|
||||
* @~English
|
||||
* @brief Create a copy of a hash list.
|
||||
*
|
||||
* @param [in,out] ppHl address of a variable in which to set a pointer to
|
||||
* the newly created hash list.
|
||||
* @param [in] orig head of the ktxHashList to copy.
|
||||
*
|
||||
* @return KTX_SUCCESS or one of the following error codes.
|
||||
* @exception KTX_OUT_OF_MEMORY if not enough memory.
|
||||
*/
|
||||
KTX_error_code
|
||||
ktxHashList_CreateCopy(ktxHashList** ppHl, ktxHashList orig)
|
||||
{
|
||||
ktxHashList* hl = (ktxHashList*)malloc(sizeof (ktxKVListEntry*));
|
||||
if (hl == NULL)
|
||||
return KTX_OUT_OF_MEMORY;
|
||||
|
||||
ktxHashList_ConstructCopy(hl, orig);
|
||||
*ppHl = hl;
|
||||
return KTX_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @memberof ktxHashList @public
|
||||
* @~English
|
||||
* @brief Destroy a hash list.
|
||||
*
|
||||
* All memory associated with the hash list's keys and values
|
||||
* is freed. The hash list is also freed.
|
||||
*
|
||||
* @param [in] pHead pointer to the hash list to be destroyed.
|
||||
*/
|
||||
void
|
||||
ktxHashList_Destroy(ktxHashList* pHead)
|
||||
{
|
||||
ktxHashList_Destruct(pHead);
|
||||
free(pHead);
|
||||
}
|
||||
|
||||
#if !__clang__ && __GNUC__ // Grumble clang grumble
|
||||
// These are in uthash.h macros. I don't want to change that file.
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wimplicit-fallthrough"
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @memberof ktxHashList @public
|
||||
* @~English
|
||||
* @brief Add a key value pair to a hash list.
|
||||
*
|
||||
* The value can be empty, i.e, its length can be 0.
|
||||
*
|
||||
* @param [in] pHead pointer to the head of the target hash list.
|
||||
* @param [in] key pointer to the UTF8 NUL-terminated string to be used as the key.
|
||||
* @param [in] valueLen the number of bytes of data in @p value.
|
||||
* @param [in] value pointer to the bytes of data constituting the value.
|
||||
*
|
||||
* @return KTX_SUCCESS or one of the following error codes.
|
||||
* @exception KTX_INVALID_VALUE if @p pHead, @p key or @p value are NULL, @p key is an
|
||||
* empty string or @p valueLen == 0.
|
||||
*/
|
||||
KTX_error_code
|
||||
ktxHashList_AddKVPair(ktxHashList* pHead, const char* key, unsigned int valueLen, const void* value)
|
||||
{
|
||||
if (pHead && key && (valueLen == 0 || value)) {
|
||||
unsigned int keyLen = (unsigned int)strlen(key) + 1;
|
||||
ktxKVListEntry* kv;
|
||||
|
||||
if (keyLen == 1)
|
||||
return KTX_INVALID_VALUE; /* Empty string */
|
||||
|
||||
/* Allocate all the memory as a block */
|
||||
kv = (ktxKVListEntry*)malloc(sizeof(ktxKVListEntry) + keyLen + valueLen);
|
||||
/* Put key first */
|
||||
kv->key = (char *)kv + sizeof(ktxKVListEntry);
|
||||
kv->keyLen = keyLen;
|
||||
memcpy(kv->key, key, keyLen);
|
||||
/* then value */
|
||||
kv->valueLen = valueLen;
|
||||
if (valueLen > 0) {
|
||||
kv->value = kv->key + keyLen;
|
||||
memcpy(kv->value, value, valueLen);
|
||||
} else {
|
||||
kv->value = 0;
|
||||
}
|
||||
|
||||
HASH_ADD_KEYPTR( hh, *pHead, kv->key, kv->keyLen-1, kv);
|
||||
return KTX_SUCCESS;
|
||||
} else
|
||||
return KTX_INVALID_VALUE;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @memberof ktxHashList @public
|
||||
* @~English
|
||||
* @brief Delete a key value pair in a hash list.
|
||||
*
|
||||
* Is a nop if the key is not in the hash.
|
||||
*
|
||||
* @param [in] pHead pointer to the head of the target hash list.
|
||||
* @param [in] key pointer to the UTF8 NUL-terminated string to be used as the key.
|
||||
*
|
||||
* @return KTX_SUCCESS or one of the following error codes.
|
||||
* @exception KTX_INVALID_VALUE if @p pHead is NULL or @p key is an empty
|
||||
* string.
|
||||
*/
|
||||
KTX_error_code
|
||||
ktxHashList_DeleteKVPair(ktxHashList* pHead, const char* key)
|
||||
{
|
||||
if (pHead && key) {
|
||||
ktxKVListEntry* kv;
|
||||
|
||||
HASH_FIND_STR( *pHead, key, kv ); /* kv: pointer to target entry. */
|
||||
if (kv != NULL)
|
||||
HASH_DEL(*pHead, kv);
|
||||
return KTX_SUCCESS;
|
||||
} else
|
||||
return KTX_INVALID_VALUE;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @memberof ktxHashList @public
|
||||
* @~English
|
||||
* @brief Delete an entry from a hash list.
|
||||
*
|
||||
* @param [in] pHead pointer to the head of the target hash list.
|
||||
* @param [in] pEntry pointer to the ktxHashListEntry to delete.
|
||||
*
|
||||
* @return KTX_SUCCESS or one of the following error codes.
|
||||
* @exception KTX_INVALID_VALUE if @p pHead is NULL or @p key is an empty
|
||||
* string.
|
||||
*/
|
||||
KTX_error_code
|
||||
ktxHashList_DeleteEntry(ktxHashList* pHead, ktxHashListEntry* pEntry)
|
||||
{
|
||||
if (pHead && pEntry) {
|
||||
HASH_DEL(*pHead, pEntry);
|
||||
return KTX_SUCCESS;
|
||||
} else
|
||||
return KTX_INVALID_VALUE;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @memberof ktxHashList @public
|
||||
* @~English
|
||||
* @brief Looks up a key in a hash list and returns the entry.
|
||||
*
|
||||
* @param [in] pHead pointer to the head of the target hash list.
|
||||
* @param [in] key pointer to a UTF8 NUL-terminated string to find.
|
||||
* @param [in,out] ppEntry @p *ppEntry is set to the point at the
|
||||
* ktxHashListEntry.
|
||||
*
|
||||
* @return KTX_SUCCESS or one of the following error codes.
|
||||
*
|
||||
* @exception KTX_INVALID_VALUE if @p This, @p key or @p pValueLen or @p ppValue
|
||||
* is NULL.
|
||||
* @exception KTX_NOT_FOUND an entry matching @p key was not found.
|
||||
*/
|
||||
KTX_error_code
|
||||
ktxHashList_FindEntry(ktxHashList* pHead, const char* key,
|
||||
ktxHashListEntry** ppEntry)
|
||||
{
|
||||
if (pHead && key) {
|
||||
ktxKVListEntry* kv;
|
||||
|
||||
HASH_FIND_STR( *pHead, key, kv ); /* kv: output pointer */
|
||||
|
||||
if (kv) {
|
||||
*ppEntry = kv;
|
||||
return KTX_SUCCESS;
|
||||
} else
|
||||
return KTX_NOT_FOUND;
|
||||
} else
|
||||
return KTX_INVALID_VALUE;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @memberof ktxHashList @public
|
||||
* @~English
|
||||
* @brief Looks up a key in a hash list and returns the value.
|
||||
*
|
||||
* @param [in] pHead pointer to the head of the target hash list.
|
||||
* @param [in] key pointer to a UTF8 NUL-terminated string to find.
|
||||
* @param [in,out] pValueLen @p *pValueLen is set to the number of bytes of
|
||||
* data in the returned value.
|
||||
* @param [in,out] ppValue @p *ppValue is set to the point to the value for
|
||||
* @p key.
|
||||
*
|
||||
* @return KTX_SUCCESS or one of the following error codes.
|
||||
*
|
||||
* @exception KTX_INVALID_VALUE if @p This, @p key or @p pValueLen or @p ppValue
|
||||
* is NULL.
|
||||
* @exception KTX_NOT_FOUND an entry matching @p key was not found.
|
||||
*/
|
||||
KTX_error_code
|
||||
ktxHashList_FindValue(ktxHashList *pHead, const char* key, unsigned int* pValueLen, void** ppValue)
|
||||
{
|
||||
if (pValueLen && ppValue) {
|
||||
ktxHashListEntry* pEntry;
|
||||
KTX_error_code result;
|
||||
|
||||
result = ktxHashList_FindEntry(pHead, key, &pEntry);
|
||||
if (result == KTX_SUCCESS) {
|
||||
ktxHashListEntry_GetValue(pEntry, pValueLen, ppValue);
|
||||
return KTX_SUCCESS;
|
||||
} else
|
||||
return result;
|
||||
} else
|
||||
return KTX_INVALID_VALUE;
|
||||
}
|
||||
|
||||
#if !__clang__ && __GNUC__
|
||||
#pragma GCC diagnostic pop
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @memberof ktxHashList @public
|
||||
* @~English
|
||||
* @brief Returns the next entry in a ktxHashList.
|
||||
*
|
||||
* Use for iterating through the list:
|
||||
* @code
|
||||
* ktxHashListEntry* entry;
|
||||
* for (entry = listHead; entry != NULL; entry = ktxHashList_Next(entry)) {
|
||||
* ...
|
||||
* };
|
||||
* @endcode
|
||||
*
|
||||
* Note
|
||||
*
|
||||
* @param [in] entry pointer to a hash list entry. Note that a ktxHashList*,
|
||||
* i.e. the list head, is also a pointer to an entry so
|
||||
* can be passed to this function.
|
||||
*
|
||||
* @return a pointer to the next entry or NULL.
|
||||
*
|
||||
*/
|
||||
ktxHashListEntry*
|
||||
ktxHashList_Next(ktxHashListEntry* entry)
|
||||
{
|
||||
if (entry) {
|
||||
return ((ktxKVListEntry*)entry)->hh.next;
|
||||
} else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @memberof ktxHashList @public
|
||||
* @~English
|
||||
* @brief Serialize a hash list to a block of data suitable for writing
|
||||
* to a file.
|
||||
*
|
||||
* The caller is responsible for freeing the data block returned by this
|
||||
* function.
|
||||
*
|
||||
* @param [in] pHead pointer to the head of the target hash list.
|
||||
* @param [in,out] pKvdLen @p *pKvdLen is set to the number of bytes of
|
||||
* data in the returned data block.
|
||||
* @param [in,out] ppKvd @p *ppKvd is set to the point to the block of
|
||||
* memory containing the serialized data or
|
||||
* NULL. if the hash list is empty.
|
||||
*
|
||||
* @return KTX_SUCCESS or one of the following error codes.
|
||||
*
|
||||
* @exception KTX_INVALID_VALUE if @p This, @p pKvdLen or @p ppKvd is NULL.
|
||||
* @exception KTX_OUT_OF_MEMORY there was not enough memory to serialize the
|
||||
* data.
|
||||
*/
|
||||
KTX_error_code
|
||||
ktxHashList_Serialize(ktxHashList* pHead,
|
||||
unsigned int* pKvdLen, unsigned char** ppKvd)
|
||||
{
|
||||
|
||||
if (pHead && pKvdLen && ppKvd) {
|
||||
ktxKVListEntry* kv;
|
||||
unsigned int bytesOfKeyValueData = 0;
|
||||
unsigned int keyValueLen;
|
||||
unsigned char* sd;
|
||||
char padding[4] = {0, 0, 0, 0};
|
||||
|
||||
for (kv = *pHead; kv != NULL; kv = kv->hh.next) {
|
||||
/* sizeof(sd) is to make space to write keyAndValueByteSize */
|
||||
keyValueLen = kv->keyLen + kv->valueLen + sizeof(ktx_uint32_t);
|
||||
/* Add valuePadding */
|
||||
keyValueLen = _KTX_PAD4(keyValueLen);
|
||||
bytesOfKeyValueData += keyValueLen;
|
||||
}
|
||||
|
||||
if (bytesOfKeyValueData == 0) {
|
||||
*pKvdLen = 0;
|
||||
*ppKvd = NULL;
|
||||
} else {
|
||||
sd = malloc(bytesOfKeyValueData);
|
||||
if (!sd)
|
||||
return KTX_OUT_OF_MEMORY;
|
||||
|
||||
*pKvdLen = bytesOfKeyValueData;
|
||||
*ppKvd = sd;
|
||||
|
||||
for (kv = *pHead; kv != NULL; kv = kv->hh.next) {
|
||||
int padLen;
|
||||
|
||||
keyValueLen = kv->keyLen + kv->valueLen;
|
||||
*(ktx_uint32_t*)sd = keyValueLen;
|
||||
sd += sizeof(ktx_uint32_t);
|
||||
memcpy(sd, kv->key, kv->keyLen);
|
||||
sd += kv->keyLen;
|
||||
if (kv->valueLen > 0)
|
||||
memcpy(sd, kv->value, kv->valueLen);
|
||||
sd += kv->valueLen;
|
||||
padLen = _KTX_PAD4_LEN(keyValueLen);
|
||||
memcpy(sd, padding, padLen);
|
||||
sd += padLen;
|
||||
}
|
||||
}
|
||||
return KTX_SUCCESS;
|
||||
} else
|
||||
return KTX_INVALID_VALUE;
|
||||
}
|
||||
|
||||
|
||||
int sort_by_key_codepoint(ktxKVListEntry* a, ktxKVListEntry* b) {
|
||||
return strcmp(a->key, b->key);
|
||||
}
|
||||
|
||||
/**
|
||||
* @memberof ktxHashList @public
|
||||
* @~English
|
||||
* @brief Sort a hash list in order of the UTF8 codepoints.
|
||||
*
|
||||
* @param [in] pHead pointer to the head of the target hash list.
|
||||
*
|
||||
* @return KTX_SUCCESS or one of the following error codes.
|
||||
*
|
||||
* @exception KTX_INVALID_VALUE if @p This is NULL.
|
||||
*/
|
||||
KTX_error_code
|
||||
ktxHashList_Sort(ktxHashList* pHead)
|
||||
{
|
||||
if (pHead) {
|
||||
//ktxKVListEntry* kv = (ktxKVListEntry*)pHead;
|
||||
|
||||
HASH_SORT(*pHead, sort_by_key_codepoint);
|
||||
return KTX_SUCCESS;
|
||||
} else {
|
||||
return KTX_INVALID_VALUE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @memberof ktxHashList @public
|
||||
* @~English
|
||||
* @brief Construct a hash list from a block of serialized key-value
|
||||
* data read from a file.
|
||||
* @note The bytes of the 32-bit key-value lengths within the serialized data
|
||||
* are expected to be in native endianness.
|
||||
*
|
||||
* @param [in] pHead pointer to the head of the target hash list.
|
||||
* @param [in] kvdLen the length of the serialized key-value data.
|
||||
* @param [in] pKvd pointer to the serialized key-value data.
|
||||
* table.
|
||||
*
|
||||
* @return KTX_SUCCESS or one of the following error codes.
|
||||
*
|
||||
* @exception KTX_INVALID_OPERATION if @p pHead does not point to an empty list.
|
||||
* @exception KTX_INVALID_VALUE if @p pKvd or @p pHt is NULL or kvdLen == 0.
|
||||
* @exception KTX_OUT_OF_MEMORY there was not enough memory to create the hash
|
||||
* table.
|
||||
*/
|
||||
KTX_error_code
|
||||
ktxHashList_Deserialize(ktxHashList* pHead, unsigned int kvdLen, void* pKvd)
|
||||
{
|
||||
char* src = pKvd;
|
||||
KTX_error_code result;
|
||||
|
||||
if (kvdLen == 0 || pKvd == NULL || pHead == NULL)
|
||||
return KTX_INVALID_VALUE;
|
||||
|
||||
if (*pHead != NULL)
|
||||
return KTX_INVALID_OPERATION;
|
||||
|
||||
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 = 0;
|
||||
|
||||
while (keyLen < keyAndValueByteSize && key[keyLen] != '\0') keyLen++;
|
||||
|
||||
if (keyLen == keyAndValueByteSize || key[keyLen] != '\0') {
|
||||
// Missing NULL terminator or no value
|
||||
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;
|
||||
result = ktxHashList_AddKVPair(pHead, key, valueLen,
|
||||
valueLen > 0 ? value : NULL);
|
||||
if (result == KTX_SUCCESS) {
|
||||
src += _KTX_PAD4(keyAndValueByteSize);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @memberof ktxHashListEntry @public
|
||||
* @~English
|
||||
* @brief Return the key of a ktxHashListEntry
|
||||
*
|
||||
* @param [in] This The target hash list entry.
|
||||
* @param [in,out] pKeyLen @p *pKeyLen is set to the byte length of
|
||||
* the returned key.
|
||||
* @param [in,out] ppKey @p *ppKey is set to the point to the value of
|
||||
* @p the key.
|
||||
*
|
||||
* @return KTX_SUCCESS or one of the following error codes.
|
||||
*
|
||||
* @exception KTX_INVALID_VALUE if @p pKvd or @p pHt is NULL or kvdLen == 0.
|
||||
*/
|
||||
KTX_error_code
|
||||
ktxHashListEntry_GetKey(ktxHashListEntry* This,
|
||||
unsigned int* pKeyLen, char** ppKey)
|
||||
{
|
||||
if (pKeyLen && ppKey) {
|
||||
ktxKVListEntry* kv = (ktxKVListEntry*)This;
|
||||
*pKeyLen = kv->keyLen;
|
||||
*ppKey = kv->key;
|
||||
return KTX_SUCCESS;
|
||||
} else
|
||||
return KTX_INVALID_VALUE;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @memberof ktxHashListEntry @public
|
||||
* @~English
|
||||
* @brief Return the value from a ktxHashListEntry
|
||||
*
|
||||
* @param [in] This The target hash list entry.
|
||||
* @param [in,out] pValueLen @p *pValueLen is set to the number of bytes of
|
||||
* data in the returned value.
|
||||
* @param [in,out] ppValue @p *ppValue is set to point to the value of
|
||||
* of the target entry.
|
||||
*
|
||||
* @return KTX_SUCCESS or one of the following error codes.
|
||||
*
|
||||
* @exception KTX_INVALID_VALUE if @p pKvd or @p pHt is NULL or kvdLen == 0.
|
||||
*/
|
||||
KTX_error_code
|
||||
ktxHashListEntry_GetValue(ktxHashListEntry* This,
|
||||
unsigned int* pValueLen, void** ppValue)
|
||||
{
|
||||
if (pValueLen && ppValue) {
|
||||
ktxKVListEntry* kv = (ktxKVListEntry*)This;
|
||||
*pValueLen = kv->valueLen;
|
||||
*ppValue = kv->valueLen > 0 ? kv->value : NULL;
|
||||
return KTX_SUCCESS;
|
||||
} else
|
||||
return KTX_INVALID_VALUE;
|
||||
}
|
348
thirdparty/libktx/lib/ktxint.h
vendored
Normal file
348
thirdparty/libktx/lib/ktxint.h
vendored
Normal file
@@ -0,0 +1,348 @@
|
||||
/* -*- tab-width: 4; -*- */
|
||||
/* vi: set sw=2 ts=4 expandtab: */
|
||||
|
||||
/* $Id$ */
|
||||
|
||||
/*
|
||||
* Copyright 2010-2020 The Khronos Group Inc.
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* Author: Mark Callow from original code by Georg Kolling
|
||||
*/
|
||||
|
||||
#ifndef KTXINT_H
|
||||
#define KTXINT_H
|
||||
|
||||
#include <math.h>
|
||||
|
||||
/* Define this to include the ETC unpack software in the library. */
|
||||
#ifndef SUPPORT_SOFTWARE_ETC_UNPACK
|
||||
/* Include for all GL versions because have seen OpenGL ES 3
|
||||
* implementaions that do not support ETC1 (ARM Mali emulator v1.0)!
|
||||
*/
|
||||
#define SUPPORT_SOFTWARE_ETC_UNPACK 1
|
||||
#endif
|
||||
|
||||
#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)
|
||||
|
||||
#define KTX2_IDENTIFIER_REF { 0xAB, 0x4B, 0x54, 0x58, 0x20, 0x32, 0x30, 0xBB, 0x0D, 0x0A, 0x1A, 0x0A }
|
||||
#define KTX2_HEADER_SIZE (80)
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @internal
|
||||
* @brief used to pass GL context capabilites to subroutines.
|
||||
*/
|
||||
#define _KTX_NO_R16_FORMATS 0x0
|
||||
#define _KTX_R16_FORMATS_NORM 0x1
|
||||
#define _KTX_R16_FORMATS_SNORM 0x2
|
||||
#define _KTX_ALL_R16_FORMATS (_KTX_R16_FORMATS_NORM | _KTX_R16_FORMATS_SNORM)
|
||||
extern GLint _ktxR16Formats;
|
||||
extern GLboolean _ktxSupportsSRGB;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
* @~English
|
||||
* @brief KTX file header.
|
||||
*
|
||||
* See the KTX specification for descriptions.
|
||||
*/
|
||||
typedef struct KTX_header {
|
||||
ktx_uint8_t identifier[12];
|
||||
ktx_uint32_t endianness;
|
||||
ktx_uint32_t glType;
|
||||
ktx_uint32_t glTypeSize;
|
||||
ktx_uint32_t glFormat;
|
||||
ktx_uint32_t glInternalformat;
|
||||
ktx_uint32_t glBaseInternalformat;
|
||||
ktx_uint32_t pixelWidth;
|
||||
ktx_uint32_t pixelHeight;
|
||||
ktx_uint32_t pixelDepth;
|
||||
ktx_uint32_t numberOfArrayElements;
|
||||
ktx_uint32_t numberOfFaces;
|
||||
ktx_uint32_t numberOfMipLevels;
|
||||
ktx_uint32_t bytesOfKeyValueData;
|
||||
} KTX_header;
|
||||
|
||||
/* This will cause compilation to fail if the struct size doesn't match */
|
||||
typedef int KTX_header_SIZE_ASSERT [sizeof(KTX_header) == KTX_HEADER_SIZE];
|
||||
|
||||
/**
|
||||
* @internal
|
||||
* @~English
|
||||
* @brief 32-bit KTX 2 index entry.
|
||||
*/
|
||||
typedef struct ktxIndexEntry32 {
|
||||
ktx_uint32_t byteOffset; /*!< Offset of item from start of file. */
|
||||
ktx_uint32_t byteLength; /*!< Number of bytes of data in the item. */
|
||||
} ktxIndexEntry32;
|
||||
/**
|
||||
* @internal
|
||||
* @~English
|
||||
* @brief 64-bit KTX 2 index entry.
|
||||
*/
|
||||
typedef struct ktxIndexEntry64 {
|
||||
ktx_uint64_t byteOffset; /*!< Offset of item from start of file. */
|
||||
ktx_uint64_t byteLength; /*!< Number of bytes of data in the item. */
|
||||
} ktxIndexEntry64;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
* @~English
|
||||
* @brief KTX 2 file header.
|
||||
*
|
||||
* See the KTX 2 specification for descriptions.
|
||||
*/
|
||||
typedef struct KTX_header2 {
|
||||
ktx_uint8_t identifier[12];
|
||||
ktx_uint32_t vkFormat;
|
||||
ktx_uint32_t typeSize;
|
||||
ktx_uint32_t pixelWidth;
|
||||
ktx_uint32_t pixelHeight;
|
||||
ktx_uint32_t pixelDepth;
|
||||
ktx_uint32_t layerCount;
|
||||
ktx_uint32_t faceCount;
|
||||
ktx_uint32_t levelCount;
|
||||
ktx_uint32_t supercompressionScheme;
|
||||
ktxIndexEntry32 dataFormatDescriptor;
|
||||
ktxIndexEntry32 keyValueData;
|
||||
ktxIndexEntry64 supercompressionGlobalData;
|
||||
} KTX_header2;
|
||||
|
||||
/* This will cause compilation to fail if the struct size doesn't match */
|
||||
typedef int KTX_header2_SIZE_ASSERT [sizeof(KTX_header2) == KTX2_HEADER_SIZE];
|
||||
|
||||
/**
|
||||
* @internal
|
||||
* @~English
|
||||
* @brief KTX 2 level index entry.
|
||||
*/
|
||||
typedef struct ktxLevelIndexEntry {
|
||||
ktx_uint64_t byteOffset; /*!< Offset of level from start of file. */
|
||||
ktx_uint64_t byteLength;
|
||||
/*!< Number of bytes of compressed image data in the level. */
|
||||
ktx_uint64_t uncompressedByteLength;
|
||||
/*!< Number of bytes of uncompressed image data in the level. */
|
||||
} ktxLevelIndexEntry;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
* @~English
|
||||
* @brief Structure for supplemental information about the texture.
|
||||
*
|
||||
* _ktxCheckHeader returns supplemental information about the texture in this
|
||||
* structure that is derived during checking of the file header.
|
||||
*/
|
||||
typedef struct KTX_supplemental_info
|
||||
{
|
||||
ktx_uint8_t compressed;
|
||||
ktx_uint8_t generateMipmaps;
|
||||
ktx_uint16_t textureDimension;
|
||||
} KTX_supplemental_info;
|
||||
/**
|
||||
* @internal
|
||||
* @var ktx_uint8_t KTX_supplemental_info::compressed
|
||||
* @~English
|
||||
* @brief KTX_TRUE, if this a compressed texture, KTX_FALSE otherwise?
|
||||
*/
|
||||
/**
|
||||
* @internal
|
||||
* @var ktx_uint8_t KTX_supplemental_info::generateMipmaps
|
||||
* @~English
|
||||
* @brief KTX_TRUE, if mipmap generation is required, KTX_FALSE otherwise.
|
||||
*/
|
||||
/**
|
||||
* @internal
|
||||
* @var ktx_uint16_t KTX_supplemental_info::textureDimension
|
||||
* @~English
|
||||
* @brief The number of dimensions, 1, 2 or 3, of data in the texture image.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @internal
|
||||
* CheckHeader1
|
||||
*
|
||||
* Reads the KTX file header and performs some sanity checking on the values
|
||||
*/
|
||||
KTX_error_code ktxCheckHeader1_(KTX_header* pHeader,
|
||||
KTX_supplemental_info* pSuppInfo);
|
||||
|
||||
/*
|
||||
* @internal
|
||||
* CheckHeader2
|
||||
*
|
||||
* Reads the KTX 2 file header and performs some sanity checking on the values
|
||||
*/
|
||||
KTX_error_code ktxCheckHeader2_(KTX_header2* pHeader,
|
||||
KTX_supplemental_info* pSuppInfo);
|
||||
|
||||
/*
|
||||
* SwapEndian16: Swaps endianness in an array of 16-bit values
|
||||
*/
|
||||
void _ktxSwapEndian16(ktx_uint16_t* pData16, ktx_size_t count);
|
||||
|
||||
/*
|
||||
* SwapEndian32: Swaps endianness in an array of 32-bit values
|
||||
*/
|
||||
void _ktxSwapEndian32(ktx_uint32_t* pData32, ktx_size_t count);
|
||||
|
||||
/*
|
||||
* SwapEndian32: Swaps endianness in an array of 64-bit values
|
||||
*/
|
||||
void _ktxSwapEndian64(ktx_uint64_t* pData64, ktx_size_t count);
|
||||
|
||||
/*
|
||||
* UnpackETC: uncompresses an ETC compressed texture image
|
||||
*/
|
||||
KTX_error_code _ktxUnpackETC(const GLubyte* srcETC, const GLenum srcFormat,
|
||||
ktx_uint32_t active_width, ktx_uint32_t active_height,
|
||||
GLubyte** dstImage,
|
||||
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
|
||||
*/
|
||||
#define _KTX_PADN(n, nbytes) (ktx_uint32_t)(n * ceilf((float)(nbytes) / n))
|
||||
/*
|
||||
* Calculate bytes of of padding needed to reach next multiple of n.
|
||||
*/
|
||||
/* Equivalent to (n * ceil(nbytes / n)) - nbytes */
|
||||
#define _KTX_PADN_LEN(n, nbytes) \
|
||||
(ktx_uint32_t)((n * ceilf((float)(nbytes) / n)) - (nbytes))
|
||||
|
||||
/*
|
||||
* Pad nbytes to next multiple of 4
|
||||
*/
|
||||
#define _KTX_PAD4(nbytes) _KTX_PADN(4, nbytes)
|
||||
/*
|
||||
* Calculate bytes of of padding needed to reach next multiple of 4.
|
||||
*/
|
||||
#define _KTX_PAD4_LEN(nbytes) _KTX_PADN_LEN(4, nbytes)
|
||||
|
||||
/*
|
||||
* Pad nbytes to next multiple of 8
|
||||
*/
|
||||
#define _KTX_PAD8(nbytes) _KTX_PADN(8, nbytes)
|
||||
/*
|
||||
* Calculate bytes of of padding needed to reach next multiple of 8.
|
||||
*/
|
||||
#define _KTX_PAD8_LEN(nbytes) _KTX_PADN_LEN(8, nbytes)
|
||||
|
||||
/*
|
||||
* Pad nbytes to KTX_GL_UNPACK_ALIGNMENT
|
||||
*/
|
||||
#define _KTX_PAD_UNPACK_ALIGN(nbytes) \
|
||||
_KTX_PADN(KTX_GL_UNPACK_ALIGNMENT, nbytes)
|
||||
/*
|
||||
* Calculate bytes of of padding needed to reach KTX_GL_UNPACK_ALIGNMENT.
|
||||
*/
|
||||
#define _KTX_PAD_UNPACK_ALIGN_LEN(nbytes) \
|
||||
_KTX_PADN_LEN(KTX_GL_UNPACK_ALIGNMENT, nbytes)
|
||||
|
||||
/*
|
||||
======================================
|
||||
Internal utility functions
|
||||
======================================
|
||||
*/
|
||||
|
||||
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
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* KTXINT_H */
|
561
thirdparty/libktx/lib/memstream.c
vendored
Normal file
561
thirdparty/libktx/lib/memstream.c
vendored
Normal file
@@ -0,0 +1,561 @@
|
||||
/* -*- tab-width: 4; -*- */
|
||||
/* vi: set sw=2 ts=4 expandtab: */
|
||||
|
||||
/*
|
||||
* Copyright 2010-2020 The Khronos Group Inc.
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file
|
||||
* @~English
|
||||
*
|
||||
* @brief Implementation of ktxStream for memory.
|
||||
*
|
||||
* @author Maksim Kolesin, Under Development
|
||||
* @author Georg Kolling, Imagination Technology
|
||||
* @author Mark Callow, HI Corporation
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "ktx.h"
|
||||
#include "ktxint.h"
|
||||
#include "memstream.h"
|
||||
|
||||
/**
|
||||
* @brief Default allocation size for a ktxMemStream.
|
||||
*/
|
||||
#define KTX_MEM_DEFAULT_ALLOCATED_SIZE 256
|
||||
|
||||
/**
|
||||
* @brief Structure to store information about data allocated for ktxMemStream.
|
||||
*/
|
||||
struct ktxMem
|
||||
{
|
||||
const ktx_uint8_t* robytes;/*!< pointer to read-only data */
|
||||
ktx_uint8_t* bytes; /*!< pointer to rw data. */
|
||||
ktx_size_t alloc_size; /*!< allocated size of the memory block. */
|
||||
ktx_size_t used_size; /*!< bytes used. Effectively the write position. */
|
||||
ktx_off_t pos; /*!< read/write position. */
|
||||
};
|
||||
|
||||
static KTX_error_code ktxMem_expand(ktxMem* pMem, const ktx_size_t size);
|
||||
|
||||
/**
|
||||
* @brief Initialize a ktxMem struct for read-write.
|
||||
*
|
||||
* Memory for the stream data is allocated internally but the
|
||||
* caller is responsible for freeing the memory. A pointer to
|
||||
* the memory can be obtained with ktxMem_getdata().
|
||||
*
|
||||
* @sa ktxMem_getdata.
|
||||
*
|
||||
* @param [in] pMem pointer to the @c ktxMem to initialize.
|
||||
*/
|
||||
static KTX_error_code
|
||||
ktxMem_construct(ktxMem* pMem)
|
||||
{
|
||||
pMem->pos = 0;
|
||||
pMem->alloc_size = 0;
|
||||
pMem->robytes = 0;
|
||||
pMem->bytes = 0;
|
||||
pMem->used_size = 0;
|
||||
return ktxMem_expand(pMem, KTX_MEM_DEFAULT_ALLOCATED_SIZE);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Create & initialize a ktxMem struct for read-write.
|
||||
*
|
||||
* @sa ktxMem_construct.
|
||||
*
|
||||
* @param [in,out] ppMem pointer to the location in which to return
|
||||
* a pointer to the newly created @c ktxMem.
|
||||
*
|
||||
* @return KTX_SUCCESS on success, KTX_OUT_OF_MEMORY on error.
|
||||
*
|
||||
* @exception KTX_OUT_OF_MEMORY System failed to allocate sufficient pMemory.
|
||||
*/
|
||||
static KTX_error_code
|
||||
ktxMem_create(ktxMem** ppMem)
|
||||
{
|
||||
ktxMem* pNewMem = (ktxMem*)malloc(sizeof(ktxMem));
|
||||
if (pNewMem) {
|
||||
KTX_error_code result = ktxMem_construct(pNewMem);
|
||||
if (result == KTX_SUCCESS)
|
||||
*ppMem = pNewMem;
|
||||
return result;
|
||||
}
|
||||
else {
|
||||
return KTX_OUT_OF_MEMORY;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Initialize a ktxMem struct for read-only.
|
||||
*
|
||||
* @param [in] pMem pointer to the @c ktxMem to initialize.
|
||||
* @param [in] bytes pointer to the data to be read.
|
||||
* @param [in] numBytes number of bytes of data.
|
||||
*/
|
||||
static void
|
||||
ktxMem_construct_ro(ktxMem* pMem, const void* bytes, ktx_size_t numBytes)
|
||||
{
|
||||
pMem->pos = 0;
|
||||
pMem->robytes = bytes;
|
||||
pMem->bytes = 0;
|
||||
pMem->used_size = numBytes;
|
||||
pMem->alloc_size = numBytes;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Create & initialize a ktxMem struct for read-only.
|
||||
*
|
||||
* @sa ktxMem_construct.
|
||||
*
|
||||
* @param [in,out] ppMem pointer to the location in which to return
|
||||
* a pointer to the newly created @c ktxMem.
|
||||
* @param [in] bytes pointer to the data to be read.
|
||||
* @param [in] numBytes number of bytes of data.
|
||||
*
|
||||
* @return KTX_SUCCESS on success, KTX_OUT_OF_MEMORY on error.
|
||||
*
|
||||
* @exception KTX_OUT_OF_MEMORY System failed to allocate sufficient pMemory.
|
||||
*/
|
||||
static KTX_error_code
|
||||
ktxMem_create_ro(ktxMem** ppMem, const void* bytes, ktx_size_t numBytes)
|
||||
{
|
||||
ktxMem* pNewMem = (ktxMem*)malloc(sizeof(ktxMem));
|
||||
if (pNewMem) {
|
||||
ktxMem_construct_ro(pNewMem, bytes, numBytes);
|
||||
*ppMem = pNewMem;
|
||||
return KTX_SUCCESS;
|
||||
}
|
||||
else {
|
||||
return KTX_OUT_OF_MEMORY;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* ktxMem_destruct not needed as ktxMem_construct caller is reponsible
|
||||
* for freeing the data written.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Free the memory of a struct ktxMem.
|
||||
*
|
||||
* @param pMem pointer to ktxMem to free.
|
||||
*/
|
||||
static void
|
||||
ktxMem_destroy(ktxMem* pMem, ktx_bool_t freeData)
|
||||
{
|
||||
assert(pMem != NULL);
|
||||
if (freeData) {
|
||||
free(pMem->bytes);
|
||||
}
|
||||
free(pMem);
|
||||
}
|
||||
|
||||
#ifdef KTXMEM_CLEAR_USED
|
||||
/**
|
||||
* @brief Clear the data of a memory stream.
|
||||
*
|
||||
* @param pMem pointer to ktxMem to clear.
|
||||
*/
|
||||
static void
|
||||
ktxMem_clear(ktxMem* pMem)
|
||||
{
|
||||
assert(pMem != NULL);
|
||||
memset(pMem, 0, sizeof(ktxMem));
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @~English
|
||||
* @brief Expand a ktxMem to fit to a new size.
|
||||
*
|
||||
* @param [in] pMem pointer to ktxMem struct to expand.
|
||||
* @param [in] newsize minimum new size required.
|
||||
*
|
||||
* @return KTX_SUCCESS on success, KTX_OUT_OF_MEMORY on error.
|
||||
*
|
||||
* @exception KTX_OUT_OF_MEMORY System failed to allocate sufficient pMemory.
|
||||
*/
|
||||
static KTX_error_code
|
||||
ktxMem_expand(ktxMem *pMem, const ktx_size_t newsize)
|
||||
{
|
||||
ktx_size_t new_alloc_size;
|
||||
|
||||
assert(pMem != NULL && newsize != 0);
|
||||
|
||||
new_alloc_size = pMem->alloc_size == 0 ?
|
||||
KTX_MEM_DEFAULT_ALLOCATED_SIZE : pMem->alloc_size;
|
||||
while (new_alloc_size < newsize) {
|
||||
ktx_size_t alloc_size = new_alloc_size;
|
||||
new_alloc_size <<= 1;
|
||||
if (new_alloc_size < alloc_size) {
|
||||
/* Overflow. Set to maximum size. newsize can't be larger. */
|
||||
new_alloc_size = (ktx_size_t)-1L;
|
||||
}
|
||||
}
|
||||
|
||||
if (new_alloc_size == pMem->alloc_size)
|
||||
return KTX_SUCCESS;
|
||||
|
||||
if (!pMem->bytes)
|
||||
pMem->bytes = (ktx_uint8_t*)malloc(new_alloc_size);
|
||||
else
|
||||
pMem->bytes = (ktx_uint8_t*)realloc(pMem->bytes, new_alloc_size);
|
||||
|
||||
if (!pMem->bytes)
|
||||
{
|
||||
pMem->alloc_size = 0;
|
||||
pMem->used_size = 0;
|
||||
return KTX_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
pMem->alloc_size = new_alloc_size;
|
||||
return KTX_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* @~English
|
||||
* @brief Read bytes from a ktxMemStream.
|
||||
*
|
||||
* @param [in] str pointer to ktxMem struct, converted to a void*, that
|
||||
* specifies an input stream.
|
||||
* @param [in,out] dst pointer to memory where to copy read bytes.
|
||||
* @param [in,out] count pointer to number of bytes to read.
|
||||
*
|
||||
* @return KTX_SUCCESS on success, KTX_INVALID_VALUE on error.
|
||||
*
|
||||
* @exception KTX_INVALID_VALUE @p str or @p dst is @c NULL or @p str->data is
|
||||
* @c NULL.
|
||||
* @exception KTX_FILE_UNEXPECTED_EOF not enough data to satisfy the request.
|
||||
*/
|
||||
static
|
||||
KTX_error_code ktxMemStream_read(ktxStream* str, void* dst, const ktx_size_t count)
|
||||
{
|
||||
ktxMem* mem;
|
||||
ktx_off_t newpos;
|
||||
const ktx_uint8_t* bytes;
|
||||
|
||||
|
||||
if (!str || (mem = str->data.mem)== 0)
|
||||
return KTX_INVALID_VALUE;
|
||||
|
||||
newpos = mem->pos + count;
|
||||
/* The first clause checks for overflow. */
|
||||
if (newpos < mem->pos || (ktx_size_t)newpos > mem->used_size)
|
||||
return KTX_FILE_UNEXPECTED_EOF;
|
||||
|
||||
bytes = mem->robytes ? mem->robytes : mem->bytes;
|
||||
memcpy(dst, bytes + mem->pos, count);
|
||||
mem->pos = newpos;
|
||||
|
||||
return KTX_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* @~English
|
||||
* @brief Skip bytes in a ktxMemStream.
|
||||
*
|
||||
* @param [in] str pointer to the ktxStream on which to operate.
|
||||
* @param [in] count number of bytes to skip.
|
||||
*
|
||||
* @return KTX_SUCCESS on success, KTX_INVALID_VALUE on error.
|
||||
*
|
||||
* @exception KTX_INVALID_VALUE @p str or @p mem is @c NULL or sufficient
|
||||
* data is not available in ktxMem.
|
||||
* @exception KTX_FILE_UNEXPECTED_EOF not enough data to satisfy the request.
|
||||
*/
|
||||
static
|
||||
KTX_error_code ktxMemStream_skip(ktxStream* str, const ktx_size_t count)
|
||||
{
|
||||
ktxMem* mem;
|
||||
ktx_off_t newpos;
|
||||
|
||||
if (!str || (mem = str->data.mem) == 0)
|
||||
return KTX_INVALID_VALUE;
|
||||
|
||||
newpos = mem->pos + count;
|
||||
/* The first clause checks for overflow. */
|
||||
if (newpos < mem->pos || (ktx_size_t)newpos > mem->used_size)
|
||||
return KTX_FILE_UNEXPECTED_EOF;
|
||||
|
||||
mem->pos = newpos;
|
||||
|
||||
return KTX_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* @~English
|
||||
* @brief Write bytes to a ktxMemStream.
|
||||
*
|
||||
* @param [out] str pointer to the ktxStream that specifies the destination.
|
||||
* @param [in] src pointer to the array of elements to be written,
|
||||
* converted to a const void*.
|
||||
* @param [in] size size in bytes of each element to be written.
|
||||
* @param [in] count number of elements, each one with a @p size of size
|
||||
* bytes.
|
||||
*
|
||||
* @return KTX_SUCCESS on success, other KTX_* enum values on error.
|
||||
*
|
||||
* @exception KTX_FILE_OVERFLOW write would result in file exceeding the
|
||||
* maximum permissible size.
|
||||
* @exception KTX_INVALID_OPERATION @p str is a read-only stream.
|
||||
* @exception KTX_INVALID_VALUE @p dst is @c NULL or @p mem is @c NULL.
|
||||
* @exception KTX_OUT_OF_MEMORY See ktxMem_expand() for causes.
|
||||
*/
|
||||
static
|
||||
KTX_error_code ktxMemStream_write(ktxStream* str, const void* src,
|
||||
const ktx_size_t size, const ktx_size_t count)
|
||||
{
|
||||
ktxMem* mem;
|
||||
KTX_error_code rc = KTX_SUCCESS;
|
||||
ktx_size_t new_size;
|
||||
|
||||
if (!str || (mem = str->data.mem) == 0)
|
||||
return KTX_INVALID_VALUE;
|
||||
|
||||
if (mem->robytes)
|
||||
return KTX_INVALID_OPERATION; /* read-only */
|
||||
|
||||
new_size = mem->pos + (size*count);
|
||||
//if (new_size < mem->used_size)
|
||||
if ((ktx_off_t)new_size < mem->pos)
|
||||
return KTX_FILE_OVERFLOW;
|
||||
|
||||
if (mem->alloc_size < new_size) {
|
||||
rc = ktxMem_expand(mem, new_size);
|
||||
if (rc != KTX_SUCCESS)
|
||||
return rc;
|
||||
}
|
||||
|
||||
memcpy(mem->bytes + mem->pos, src, size*count);
|
||||
mem->pos += size*count;
|
||||
if (mem->pos > (ktx_off_t)mem->used_size)
|
||||
mem->used_size = mem->pos;
|
||||
|
||||
|
||||
return KTX_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* @~English
|
||||
* @brief Get the current read/write position in a ktxMemStream.
|
||||
*
|
||||
* @param [in] str pointer to the ktxStream to query.
|
||||
* @param [in,out] off pointer to variable to receive the offset value.
|
||||
*
|
||||
* @return KTX_SUCCESS on success, other KTX_* enum values on error.
|
||||
*
|
||||
* @exception KTX_INVALID_VALUE @p str or @p pos is @c NULL.
|
||||
*/
|
||||
static
|
||||
KTX_error_code ktxMemStream_getpos(ktxStream* str, ktx_off_t* const pos)
|
||||
{
|
||||
if (!str || !pos)
|
||||
return KTX_INVALID_VALUE;
|
||||
|
||||
assert(str->type == eStreamTypeMemory);
|
||||
|
||||
*pos = str->data.mem->pos;
|
||||
return KTX_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* @~English
|
||||
* @brief Set the current read/write position in a ktxMemStream.
|
||||
*
|
||||
* Offset of 0 is the start of the file.
|
||||
*
|
||||
* @param [in] str pointer to the ktxStream whose r/w position is to be set.
|
||||
* @param [in] off pointer to the offset value to set.
|
||||
*
|
||||
* @return KTX_SUCCESS on success, other KTX_* enum values on error.
|
||||
*
|
||||
* @exception KTX_INVALID_VALUE @p str is @c NULL.
|
||||
* @exception KTX_INVALID_OPERATION @p pos > size of the allocated memory.
|
||||
*/
|
||||
static
|
||||
KTX_error_code ktxMemStream_setpos(ktxStream* str, ktx_off_t pos)
|
||||
{
|
||||
if (!str)
|
||||
return KTX_INVALID_VALUE;
|
||||
|
||||
assert(str->type == eStreamTypeMemory);
|
||||
|
||||
if (pos < 0 || (ktx_size_t)pos > str->data.mem->alloc_size)
|
||||
return KTX_INVALID_OPERATION;
|
||||
|
||||
str->data.mem->pos = pos;
|
||||
return KTX_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* @~English
|
||||
* @brief Get a pointer to a ktxMemStream's data.
|
||||
*
|
||||
* Gets a pointer to data that has been written to the stream. Returned
|
||||
* pointer will be 0 if stream is read-only.
|
||||
*
|
||||
* @param [in] str pointer to the ktxStream whose data pointer is to
|
||||
* be queried.
|
||||
* @param [in,out] ppBytes pointer to a variable in which the data pointer
|
||||
* will be written.
|
||||
*
|
||||
* @return KTX_SUCCESS on success, other KTX_* enum values on error.
|
||||
*
|
||||
* @exception KTX_INVALID_VALUE @p str or @p ppBytes is @c NULL.
|
||||
*/
|
||||
KTX_error_code ktxMemStream_getdata(ktxStream* str, ktx_uint8_t** ppBytes)
|
||||
{
|
||||
if (!str || !ppBytes)
|
||||
return KTX_INVALID_VALUE;
|
||||
|
||||
assert(str->type == eStreamTypeMemory);
|
||||
|
||||
*ppBytes = str->data.mem->bytes;
|
||||
return KTX_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* @~English
|
||||
* @brief Get the size of a ktxMemStream in bytes.
|
||||
*
|
||||
* @param [in] str pointer to the ktxStream whose size is to be queried.
|
||||
* @param [in,out] size pointer to a variable in which size will be written.
|
||||
*
|
||||
* @return KTX_SUCCESS on success, other KTX_* enum values on error.
|
||||
*
|
||||
* @exception KTX_INVALID_VALUE @p str or @p pSize is @c NULL.
|
||||
*/
|
||||
static
|
||||
KTX_error_code ktxMemStream_getsize(ktxStream* str, ktx_size_t* pSize)
|
||||
{
|
||||
if (!str || !pSize)
|
||||
return KTX_INVALID_VALUE;
|
||||
|
||||
assert(str->type == eStreamTypeMemory);
|
||||
|
||||
*pSize = str->data.mem->used_size;
|
||||
return KTX_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* @~English
|
||||
* @brief Setup ktxMemStream function pointers.
|
||||
*/
|
||||
void
|
||||
ktxMemStream_setup(ktxStream* str)
|
||||
{
|
||||
str->type = eStreamTypeMemory;
|
||||
str->read = ktxMemStream_read;
|
||||
str->skip = ktxMemStream_skip;
|
||||
str->write = ktxMemStream_write;
|
||||
str->getpos = ktxMemStream_getpos;
|
||||
str->setpos = ktxMemStream_setpos;
|
||||
str->getsize = ktxMemStream_getsize;
|
||||
str->destruct = ktxMemStream_destruct;
|
||||
}
|
||||
|
||||
/**
|
||||
* @~English
|
||||
* @brief Initialize a read-write ktxMemStream.
|
||||
*
|
||||
* Memory is allocated as data is written. The caller of this is
|
||||
* responsible for freeing this memory unless @a freeOnDestruct
|
||||
* is not KTX_FALSE.
|
||||
*
|
||||
* @param [in] str pointer to a ktxStream struct to initialize.
|
||||
* @param [in] freeOnDestruct If not KTX_FALSE memory holding the data will
|
||||
* be freed by the destructor.
|
||||
*
|
||||
* @return KTX_SUCCESS on success, other KTX_* enum values on error.
|
||||
*
|
||||
* @exception KTX_INVALID_VALUE @p str is @c NULL.
|
||||
* @exception KTX_OUT_OF_MEMORY system failed to allocate sufficient memory.
|
||||
*/
|
||||
KTX_error_code ktxMemStream_construct(ktxStream* str,
|
||||
ktx_bool_t freeOnDestruct)
|
||||
{
|
||||
ktxMem* mem;
|
||||
KTX_error_code result = KTX_SUCCESS;
|
||||
|
||||
if (!str)
|
||||
return KTX_INVALID_VALUE;
|
||||
|
||||
result = ktxMem_create(&mem);
|
||||
|
||||
if (KTX_SUCCESS == result) {
|
||||
str->data.mem = mem;
|
||||
ktxMemStream_setup(str);
|
||||
str->closeOnDestruct = freeOnDestruct;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @~English
|
||||
* @brief Initialize a read-only ktxMemStream.
|
||||
*
|
||||
* @param [in] str pointer to a ktxStream struct to initialize.
|
||||
* @param [in] bytes pointer to an array of bytes containing the data.
|
||||
* @param [in] numBytes size of array of data for ktxMemStream.
|
||||
*
|
||||
* @return KTX_SUCCESS on success, other KTX_* enum values on error.
|
||||
*
|
||||
* @exception KTX_INVALID_VALUE @p str or @p mem is @c NULL or @p numBytes
|
||||
* is 0.
|
||||
* or @p size is less than 0.
|
||||
* @exception KTX_OUT_OF_MEMORY system failed to allocate sufficient memory.
|
||||
*/
|
||||
KTX_error_code ktxMemStream_construct_ro(ktxStream* str,
|
||||
const ktx_uint8_t* bytes,
|
||||
const ktx_size_t numBytes)
|
||||
{
|
||||
ktxMem* mem;
|
||||
KTX_error_code result = KTX_SUCCESS;
|
||||
|
||||
if (!str || !bytes || numBytes == 0)
|
||||
return KTX_INVALID_VALUE;
|
||||
|
||||
result = ktxMem_create_ro(&mem, bytes, numBytes);
|
||||
|
||||
if (KTX_SUCCESS == result) {
|
||||
str->data.mem = mem;
|
||||
ktxMemStream_setup(str);
|
||||
str->closeOnDestruct = KTX_FALSE;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @~English
|
||||
* @brief Free the memory used by a ktxMemStream.
|
||||
*
|
||||
* This only frees the memory used to store the data written to the stream,
|
||||
* if the @c freeOnDestruct parameter to ktxMemStream_construct() was not
|
||||
* @c KTX_FALSE. Otherwise it is the responsibility of the caller of
|
||||
* ktxMemStream_construct() and a pointer to this memory should be retrieved
|
||||
* using ktxMemStream_getdata() before calling this function.
|
||||
*
|
||||
* @sa ktxMemStream_construct, ktxMemStream_getdata.
|
||||
*
|
||||
* @param [in] str pointer to the ktxStream whose memory is
|
||||
* to be freed.
|
||||
*/
|
||||
void
|
||||
ktxMemStream_destruct(ktxStream* str)
|
||||
{
|
||||
assert(str && str->type == eStreamTypeMemory);
|
||||
|
||||
ktxMem_destroy(str->data.mem, str->closeOnDestruct);
|
||||
str->data.mem = NULL;
|
||||
}
|
||||
|
43
thirdparty/libktx/lib/memstream.h
vendored
Normal file
43
thirdparty/libktx/lib/memstream.h
vendored
Normal file
@@ -0,0 +1,43 @@
|
||||
/* -*- tab-width: 4; -*- */
|
||||
/* vi: set sw=2 ts=4 expandtab: */
|
||||
|
||||
/*
|
||||
* Copyright 2010-2020 The Khronos Group Inc.
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
/**
|
||||
* @internal
|
||||
* @file
|
||||
* @~English
|
||||
*
|
||||
* @brief Interface of ktxStream for memory.
|
||||
*
|
||||
* @author Maksim Kolesin
|
||||
* @author Georg Kolling, Imagination Technology
|
||||
* @author Mark Callow, HI Corporation
|
||||
*/
|
||||
|
||||
#ifndef MEMSTREAM_H
|
||||
#define MEMSTREAM_H
|
||||
|
||||
#include "ktx.h"
|
||||
|
||||
/*
|
||||
* Initialize a ktxStream to a ktxMemStream with internally
|
||||
* allocated memory. Can be read or written.
|
||||
*/
|
||||
KTX_error_code ktxMemStream_construct(ktxStream* str,
|
||||
ktx_bool_t freeOnDestruct);
|
||||
/*
|
||||
* Initialize a ktxStream to a read-only ktxMemStream reading
|
||||
* from an array of bytes.
|
||||
*/
|
||||
KTX_error_code ktxMemStream_construct_ro(ktxStream* str,
|
||||
const ktx_uint8_t* pBytes,
|
||||
const ktx_size_t size);
|
||||
void ktxMemStream_destruct(ktxStream* str);
|
||||
|
||||
KTX_error_code ktxMemStream_getdata(ktxStream* str, ktx_uint8_t** ppBytes);
|
||||
|
||||
#endif /* MEMSTREAM_H */
|
149
thirdparty/libktx/lib/miniz_wrapper.cpp
vendored
Normal file
149
thirdparty/libktx/lib/miniz_wrapper.cpp
vendored
Normal file
@@ -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
|
||||
* @~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;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
57
thirdparty/libktx/lib/swap.c
vendored
Normal file
57
thirdparty/libktx/lib/swap.c
vendored
Normal file
@@ -0,0 +1,57 @@
|
||||
/* -*- tab-width: 4; -*- */
|
||||
/* vi: set sw=2 ts=4 expandtab: */
|
||||
|
||||
/* $Id$ */
|
||||
|
||||
/*
|
||||
* Copyright 2010-2020 The Khronos Group Inc.
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <KHR/khrplatform.h>
|
||||
#include "ktx.h"
|
||||
|
||||
/*
|
||||
* SwapEndian16: Swaps endianness in an array of 16-bit values
|
||||
*/
|
||||
void
|
||||
_ktxSwapEndian16(khronos_uint16_t* pData16, ktx_size_t count)
|
||||
{
|
||||
for (ktx_size_t i = 0; i < count; ++i)
|
||||
{
|
||||
khronos_uint16_t x = *pData16;
|
||||
*pData16++ = (x << 8) | (x >> 8);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* SwapEndian32: Swaps endianness in an array of 32-bit values
|
||||
*/
|
||||
void
|
||||
_ktxSwapEndian32(khronos_uint32_t* pData32, ktx_size_t count)
|
||||
{
|
||||
for (ktx_size_t i = 0; i < count; ++i)
|
||||
{
|
||||
khronos_uint32_t x = *pData32;
|
||||
*pData32++ = (x << 24) | ((x & 0xFF00) << 8) | ((x & 0xFF0000) >> 8) | (x >> 24);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* SwapEndian364: Swaps endianness in an array of 32-bit values
|
||||
*/
|
||||
void
|
||||
_ktxSwapEndian64(khronos_uint64_t* pData64, ktx_size_t count)
|
||||
{
|
||||
for (ktx_size_t i = 0; i < count; ++i)
|
||||
{
|
||||
khronos_uint64_t x = *pData64;
|
||||
*pData64++ = (x << 56) | ((x & 0xFF00) << 40) | ((x & 0xFF0000) << 24)
|
||||
| ((x & 0xFF000000) << 8 ) | ((x & 0xFF00000000) >> 8)
|
||||
| ((x & 0xFF0000000000) >> 24)
|
||||
| ((x & 0xFF000000000000) << 40) | (x >> 56);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
882
thirdparty/libktx/lib/texture.c
vendored
Normal file
882
thirdparty/libktx/lib/texture.c
vendored
Normal file
@@ -0,0 +1,882 @@
|
||||
/* -*- tab-width: 4; -*- */
|
||||
/* vi: set sw=2 ts=4 expandtab: */
|
||||
|
||||
/*
|
||||
* Copyright 2018-2020 Mark Callow.
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
/**
|
||||
* @internal
|
||||
* @file
|
||||
* @~English
|
||||
*
|
||||
* @brief ktxTexture implementation.
|
||||
*
|
||||
* @author Mark Callow, www.edgewise-consulting.com
|
||||
*/
|
||||
|
||||
#if defined(_WIN32)
|
||||
#define _CRT_SECURE_NO_WARNINGS
|
||||
#ifndef __cplusplus
|
||||
#undef inline
|
||||
#define inline __inline
|
||||
#endif // __cplusplus
|
||||
#endif
|
||||
|
||||
#include <assert.h>
|
||||
#include <math.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "ktx.h"
|
||||
#include "ktxint.h"
|
||||
#include "formatsize.h"
|
||||
#include "filestream.h"
|
||||
#include "memstream.h"
|
||||
#include "texture1.h"
|
||||
#include "texture2.h"
|
||||
#include "unused.h"
|
||||
|
||||
ktx_size_t ktxTexture_GetDataSize(ktxTexture* This);
|
||||
|
||||
static ktx_uint32_t padRow(ktx_uint32_t* rowBytes);
|
||||
|
||||
/**
|
||||
* @memberof ktxTexture @private
|
||||
* @~English
|
||||
* @brief Construct (initialize) a ktxTexture base class instance.
|
||||
*
|
||||
* @param[in] This pointer to a ktxTexture-sized block of memory to
|
||||
* initialize.
|
||||
* @param[in] createInfo pointer to a ktxTextureCreateInfo struct with
|
||||
* information describing the texture.
|
||||
* @param[in] formatSize pointer to a ktxFormatSize giving size information
|
||||
* about the texture's elements.
|
||||
*
|
||||
* @return KTX_SUCCESS on success, other KTX_* enum values on error.
|
||||
*
|
||||
* @exception KTX_INVALID_VALUE @c glInternalFormat in @p createInfo is not a
|
||||
* valid OpenGL internal format value.
|
||||
* @exception KTX_INVALID_VALUE @c numDimensions in @p createInfo is not 1, 2
|
||||
* or 3.
|
||||
* @exception KTX_INVALID_VALUE One of <tt>base{Width,Height,Depth}</tt> in
|
||||
* @p createInfo is 0.
|
||||
* @exception KTX_INVALID_VALUE @c numFaces in @p createInfo is not 1 or 6.
|
||||
* @exception KTX_INVALID_VALUE @c numLevels in @p createInfo is 0.
|
||||
* @exception KTX_INVALID_OPERATION
|
||||
* The <tt>base{Width,Height,Depth}</tt> specified
|
||||
* in @p createInfo are inconsistent with
|
||||
* @c numDimensions.
|
||||
* @exception KTX_INVALID_OPERATION
|
||||
* @p createInfo is requesting a 3D array or
|
||||
* 3D cubemap texture.
|
||||
* @exception KTX_INVALID_OPERATION
|
||||
* @p createInfo is requesting a cubemap with
|
||||
* non-square or non-2D images.
|
||||
* @exception KTX_INVALID_OPERATION
|
||||
* @p createInfo is requesting more mip levels
|
||||
* than needed for the specified
|
||||
* <tt>base{Width,Height,Depth}</tt>.
|
||||
* @exception KTX_OUT_OF_MEMORY Not enough memory for the texture.
|
||||
*/
|
||||
KTX_error_code
|
||||
ktxTexture_construct(ktxTexture* This,
|
||||
const ktxTextureCreateInfo* const createInfo,
|
||||
ktxFormatSize* formatSize)
|
||||
{
|
||||
DECLARE_PROTECTED(ktxTexture);
|
||||
|
||||
memset(This, 0, sizeof(*This));
|
||||
This->_protected = (struct ktxTexture_protected*)malloc(sizeof(*prtctd));
|
||||
if (!This->_protected)
|
||||
return KTX_OUT_OF_MEMORY;
|
||||
prtctd = This->_protected;
|
||||
memset(prtctd, 0, sizeof(*prtctd));
|
||||
memcpy(&prtctd->_formatSize, formatSize, sizeof(prtctd->_formatSize));
|
||||
|
||||
This->isCompressed = (formatSize->flags & KTX_FORMAT_SIZE_COMPRESSED_BIT);
|
||||
|
||||
This->orientation.x = KTX_ORIENT_X_RIGHT;
|
||||
This->orientation.y = KTX_ORIENT_Y_DOWN;
|
||||
This->orientation.z = KTX_ORIENT_Z_OUT;
|
||||
|
||||
/* Check texture dimensions. KTX files can store 8 types of textures:
|
||||
* 1D, 2D, 3D, cube, and array variants of these.
|
||||
*/
|
||||
if (createInfo->numDimensions < 1 || createInfo->numDimensions > 3)
|
||||
return KTX_INVALID_VALUE;
|
||||
|
||||
if (createInfo->baseWidth == 0 || createInfo->baseHeight == 0
|
||||
|| createInfo->baseDepth == 0)
|
||||
return KTX_INVALID_VALUE;
|
||||
|
||||
switch (createInfo->numDimensions) {
|
||||
case 1:
|
||||
if (createInfo->baseHeight > 1 || createInfo->baseDepth > 1)
|
||||
return KTX_INVALID_OPERATION;
|
||||
break;
|
||||
|
||||
case 2:
|
||||
if (createInfo->baseDepth > 1)
|
||||
return KTX_INVALID_OPERATION;
|
||||
break;
|
||||
|
||||
case 3:
|
||||
/* 3D array textures and 3D cubemaps are not supported by either
|
||||
* OpenGL or Vulkan.
|
||||
*/
|
||||
if (createInfo->isArray || createInfo->numFaces != 1
|
||||
|| createInfo->numLayers != 1)
|
||||
return KTX_INVALID_OPERATION;
|
||||
break;
|
||||
}
|
||||
This->numDimensions = createInfo->numDimensions;
|
||||
This->baseWidth = createInfo->baseWidth;
|
||||
This->baseDepth = createInfo->baseDepth;
|
||||
This->baseHeight = createInfo->baseHeight;
|
||||
|
||||
if (createInfo->numLayers == 0)
|
||||
return KTX_INVALID_VALUE;
|
||||
This->numLayers = createInfo->numLayers;
|
||||
This->isArray = createInfo->isArray;
|
||||
|
||||
if (createInfo->numFaces == 6) {
|
||||
if (This->numDimensions != 2) {
|
||||
/* cube map needs 2D faces */
|
||||
return KTX_INVALID_OPERATION;
|
||||
}
|
||||
if (createInfo->baseWidth != createInfo->baseHeight) {
|
||||
/* cube maps require square images */
|
||||
return KTX_INVALID_OPERATION;
|
||||
}
|
||||
This->isCubemap = KTX_TRUE;
|
||||
} else if (createInfo->numFaces != 1) {
|
||||
/* numFaces must be either 1 or 6 */
|
||||
return KTX_INVALID_VALUE;
|
||||
}
|
||||
This->numFaces = createInfo->numFaces;
|
||||
|
||||
/* Check number of mipmap levels */
|
||||
if (createInfo->numLevels == 0)
|
||||
return KTX_INVALID_VALUE;
|
||||
This->numLevels = createInfo->numLevels;
|
||||
This->generateMipmaps = createInfo->generateMipmaps;
|
||||
|
||||
if (createInfo->numLevels > 1) {
|
||||
GLuint max_dim = MAX(MAX(createInfo->baseWidth, createInfo->baseHeight),
|
||||
createInfo->baseDepth);
|
||||
if (max_dim < ((GLuint)1 << (This->numLevels - 1)))
|
||||
{
|
||||
/* Can't have more mip levels than 1 + log2(max(width, height, depth)) */
|
||||
return KTX_INVALID_OPERATION;
|
||||
}
|
||||
}
|
||||
|
||||
ktxHashList_Construct(&This->kvDataHead);
|
||||
return KTX_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* @memberof ktxTexture @private
|
||||
* @~English
|
||||
* @brief Construct (initialize) the part of a ktxTexture base class that is
|
||||
* not related to the stream contents.
|
||||
*
|
||||
* @param[in] This pointer to a ktxTexture-sized block of memory to
|
||||
* initialize.
|
||||
*
|
||||
* @return KTX_SUCCESS on success, other KTX_* enum values on error.
|
||||
*/
|
||||
KTX_error_code
|
||||
ktxTexture_constructFromStream(ktxTexture* This, ktxStream* pStream,
|
||||
ktxTextureCreateFlags createFlags)
|
||||
{
|
||||
ktxStream* stream;
|
||||
UNUSED(createFlags); // Reference to keep compiler happy.
|
||||
|
||||
assert(This != NULL);
|
||||
assert(pStream->data.mem != NULL);
|
||||
assert(pStream->type == eStreamTypeFile
|
||||
|| pStream->type == eStreamTypeMemory
|
||||
|| pStream->type == eStreamTypeCustom);
|
||||
|
||||
This->_protected = (struct ktxTexture_protected *)
|
||||
malloc(sizeof(struct ktxTexture_protected));
|
||||
stream = ktxTexture_getStream(This);
|
||||
// Copy stream info into struct for later use.
|
||||
*stream = *pStream;
|
||||
|
||||
This->orientation.x = KTX_ORIENT_X_RIGHT;
|
||||
This->orientation.y = KTX_ORIENT_Y_DOWN;
|
||||
This->orientation.z = KTX_ORIENT_Z_OUT;
|
||||
|
||||
return KTX_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @memberof ktxTexture @private
|
||||
* @~English
|
||||
* @brief Free the memory associated with the texture contents
|
||||
*
|
||||
* @param[in] This pointer to the ktxTextureInt whose texture contents are
|
||||
* to be freed.
|
||||
*/
|
||||
void
|
||||
ktxTexture_destruct(ktxTexture* This)
|
||||
{
|
||||
ktxStream stream = *(ktxTexture_getStream(This));
|
||||
|
||||
if (stream.data.file != NULL)
|
||||
stream.destruct(&stream);
|
||||
if (This->kvDataHead != NULL)
|
||||
ktxHashList_Destruct(&This->kvDataHead);
|
||||
if (This->kvData != NULL)
|
||||
free(This->kvData);
|
||||
if (This->pData != NULL)
|
||||
free(This->pData);
|
||||
free(This->_protected);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @defgroup reader Reader
|
||||
* @brief Read KTX-formatted data.
|
||||
* @{
|
||||
*/
|
||||
|
||||
typedef enum { KTX1, KTX2 } ktxFileType_;
|
||||
typedef union {
|
||||
KTX_header ktx;
|
||||
KTX_header2 ktx2;
|
||||
} ktxHeaderUnion_;
|
||||
|
||||
/**
|
||||
* @memberof ktxTexture @private
|
||||
* @~English
|
||||
* @brief Determine if stream data is KTX1 or KTX2.
|
||||
*
|
||||
* @param pStream pointer to the ktxStream to examine.
|
||||
* @param pFileType pointer to a ktxFileType enum where the type of the data
|
||||
* will be written.
|
||||
* @param pHeader pointer to a ktxHeaderUnion where the header info. will be
|
||||
* written.
|
||||
*/
|
||||
static KTX_error_code
|
||||
ktxDetermineFileType_(ktxStream* pStream, ktxFileType_* pFileType,
|
||||
ktxHeaderUnion_* pHeader)
|
||||
{
|
||||
ktx_uint8_t ktx_ident_ref[12] = KTX_IDENTIFIER_REF;
|
||||
ktx_uint8_t ktx2_ident_ref[12] = KTX2_IDENTIFIER_REF;
|
||||
KTX_error_code result;
|
||||
|
||||
assert(pStream != NULL && pFileType != NULL);
|
||||
assert(pStream->data.mem != NULL);
|
||||
assert(pStream->type == eStreamTypeFile
|
||||
|| pStream->type == eStreamTypeMemory
|
||||
|| pStream->type == eStreamTypeCustom);
|
||||
|
||||
result = pStream->read(pStream, pHeader, sizeof(ktx2_ident_ref));
|
||||
if (result == KTX_SUCCESS) {
|
||||
#if BIG_ENDIAN
|
||||
// byte swap the heaader fields
|
||||
#endif
|
||||
// Compare identifier, is this a KTX or KTX2 file?
|
||||
if (!memcmp(pHeader->ktx.identifier, ktx_ident_ref, 12)) {
|
||||
*pFileType = KTX1;
|
||||
} else if (!memcmp(pHeader->ktx2.identifier, ktx2_ident_ref, 12)) {
|
||||
*pFileType = KTX2;
|
||||
} else {
|
||||
return KTX_UNKNOWN_FILE_FORMAT;
|
||||
}
|
||||
// Read rest of header.
|
||||
if (*pFileType == KTX1) {
|
||||
// Read rest of header.
|
||||
result = pStream->read(pStream, &pHeader->ktx.endianness,
|
||||
KTX_HEADER_SIZE - sizeof(ktx_ident_ref));
|
||||
} else {
|
||||
result = pStream->read(pStream, &pHeader->ktx2.vkFormat,
|
||||
KTX2_HEADER_SIZE - sizeof(ktx2_ident_ref));
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @memberof ktxTexture
|
||||
* @~English
|
||||
* @brief Create a ktx1 or ktx2 texture according to the stream
|
||||
* data.
|
||||
*
|
||||
* See @ref ktxTexture1::ktxTexture1_CreateFromStream
|
||||
* "ktxTexture1_CreateFromStream" or
|
||||
* @ref ktxTexture2::ktxTexture2_CreateFromStream
|
||||
* "ktxTexture2_CreateFromStream" for details.
|
||||
*/
|
||||
KTX_error_code
|
||||
ktxTexture_CreateFromStream(ktxStream* pStream,
|
||||
ktxTextureCreateFlags createFlags,
|
||||
ktxTexture** newTex)
|
||||
{
|
||||
ktxHeaderUnion_ header;
|
||||
ktxFileType_ fileType;
|
||||
KTX_error_code result;
|
||||
ktxTexture* tex;
|
||||
|
||||
result = ktxDetermineFileType_(pStream, &fileType, &header);
|
||||
if (result != KTX_SUCCESS)
|
||||
return result;
|
||||
|
||||
if (fileType == KTX1) {
|
||||
ktxTexture1* tex1 = (ktxTexture1*)malloc(sizeof(ktxTexture1));
|
||||
if (tex1 == NULL)
|
||||
return KTX_OUT_OF_MEMORY;
|
||||
memset(tex1, 0, sizeof(ktxTexture1));
|
||||
result = ktxTexture1_constructFromStreamAndHeader(tex1, pStream,
|
||||
&header.ktx,
|
||||
createFlags);
|
||||
tex = ktxTexture(tex1);
|
||||
} else {
|
||||
ktxTexture2* tex2 = (ktxTexture2*)malloc(sizeof(ktxTexture2));
|
||||
if (tex2 == NULL)
|
||||
return KTX_OUT_OF_MEMORY;
|
||||
memset(tex2, 0, sizeof(ktxTexture2));
|
||||
result = ktxTexture2_constructFromStreamAndHeader(tex2, pStream,
|
||||
&header.ktx2,
|
||||
createFlags);
|
||||
tex = ktxTexture(tex2);
|
||||
}
|
||||
|
||||
if (result == KTX_SUCCESS)
|
||||
*newTex = (ktxTexture*)tex;
|
||||
else {
|
||||
free(tex);
|
||||
*newTex = NULL;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @memberof ktxTexture
|
||||
* @~English
|
||||
* @brief Create a ktxTexture1 or ktxTexture2 from a stdio stream according
|
||||
* to the stream data.
|
||||
*
|
||||
* See @ref ktxTexture1::ktxTexture1_CreateFromStdioStream
|
||||
* "ktxTexture1_CreateFromStdioStream" or
|
||||
* @ref ktxTexture2::ktxTexture2_CreateFromStdioStream
|
||||
* "ktxTexture2_CreateFromStdioStream" for details.
|
||||
*/
|
||||
KTX_error_code
|
||||
ktxTexture_CreateFromStdioStream(FILE* stdioStream,
|
||||
ktxTextureCreateFlags createFlags,
|
||||
ktxTexture** newTex)
|
||||
{
|
||||
ktxStream stream;
|
||||
KTX_error_code result;
|
||||
|
||||
if (stdioStream == NULL || newTex == NULL)
|
||||
return KTX_INVALID_VALUE;
|
||||
|
||||
result = ktxFileStream_construct(&stream, stdioStream, KTX_FALSE);
|
||||
if (result == KTX_SUCCESS) {
|
||||
result = ktxTexture_CreateFromStream(&stream, createFlags, newTex);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @memberof ktxTexture
|
||||
* @~English
|
||||
* @brief Create a ktxTexture1 or ktxTexture2 from a named KTX file according
|
||||
* to the file contents.
|
||||
*
|
||||
* 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,
|
||||
ktxTextureCreateFlags createFlags,
|
||||
ktxTexture** newTex)
|
||||
{
|
||||
KTX_error_code result;
|
||||
ktxStream stream;
|
||||
FILE* file;
|
||||
|
||||
if (filename == NULL || newTex == NULL)
|
||||
return KTX_INVALID_VALUE;
|
||||
|
||||
file = ktxFOpenUTF8(filename, "rb");
|
||||
if (!file)
|
||||
return KTX_FILE_OPEN_FAILED;
|
||||
|
||||
result = ktxFileStream_construct(&stream, file, KTX_TRUE);
|
||||
if (result == KTX_SUCCESS) {
|
||||
result = ktxTexture_CreateFromStream(&stream, createFlags, newTex);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @memberof ktxTexture
|
||||
* @~English
|
||||
* @brief Create a ktxTexture1 or ktxTexture2 from KTX-formatted data in memory
|
||||
* according to the data contents.
|
||||
*
|
||||
* 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,
|
||||
ktxTextureCreateFlags createFlags,
|
||||
ktxTexture** newTex)
|
||||
{
|
||||
KTX_error_code result;
|
||||
ktxStream stream;
|
||||
|
||||
if (bytes == NULL || newTex == NULL || size == 0)
|
||||
return KTX_INVALID_VALUE;
|
||||
|
||||
result = ktxMemStream_construct_ro(&stream, bytes, size);
|
||||
if (result == KTX_SUCCESS) {
|
||||
result = ktxTexture_CreateFromStream(&stream, createFlags, newTex);
|
||||
}
|
||||
return result;}
|
||||
|
||||
|
||||
/**
|
||||
* @memberof ktxTexture
|
||||
* @~English
|
||||
* @brief Return a pointer to the texture image data.
|
||||
*
|
||||
* @param[in] This pointer to the ktxTexture object of interest.
|
||||
*/
|
||||
ktx_uint8_t*
|
||||
ktxTexture_GetData(ktxTexture* This)
|
||||
{
|
||||
return This->pData;
|
||||
}
|
||||
|
||||
/**
|
||||
* @memberof ktxTexture
|
||||
* @~English
|
||||
* @brief Return the total size of the texture image data in bytes.
|
||||
*
|
||||
* For a ktxTexture2 with supercompressionScheme != KTX_SS_NONE this will
|
||||
* return the deflated size of the data.
|
||||
*
|
||||
* @param[in] This pointer to the ktxTexture object of interest.
|
||||
*/
|
||||
ktx_size_t
|
||||
ktxTexture_GetDataSize(ktxTexture* This)
|
||||
{
|
||||
assert(This != NULL);
|
||||
return This->dataSize;
|
||||
}
|
||||
|
||||
/**
|
||||
* @memberof ktxTexture
|
||||
* @~English
|
||||
* @brief Return the size in bytes of an elements of a texture's
|
||||
* images.
|
||||
*
|
||||
* For uncompressed textures an element is one texel. For compressed
|
||||
* textures it is one block.
|
||||
*
|
||||
* @param[in] This pointer to the ktxTexture object of interest.
|
||||
*/
|
||||
ktx_uint32_t
|
||||
ktxTexture_GetElementSize(ktxTexture* This)
|
||||
{
|
||||
assert (This != NULL);
|
||||
|
||||
return (This->_protected->_formatSize.blockSizeInBits / 8);
|
||||
}
|
||||
|
||||
/**
|
||||
* @memberof ktxTexture @private
|
||||
* @~English
|
||||
* @brief Calculate & return the size in bytes of an image at the specified
|
||||
* mip level.
|
||||
*
|
||||
* For arrays, this is the size of layer, for cubemaps, the size of a face
|
||||
* and for 3D textures, the size of a depth slice.
|
||||
*
|
||||
* The size reflects the padding of each row to KTX_GL_UNPACK_ALIGNMENT.
|
||||
*
|
||||
* @param[in] This pointer to the ktxTexture object of interest.
|
||||
* @param[in] level level of interest.
|
||||
* @param[in] fv enum specifying format version for which to calculate
|
||||
* image size.
|
||||
*/
|
||||
ktx_size_t
|
||||
ktxTexture_calcImageSize(ktxTexture* This, ktx_uint32_t level,
|
||||
ktxFormatVersionEnum fv)
|
||||
{
|
||||
DECLARE_PROTECTED(ktxTexture);
|
||||
struct blockCount {
|
||||
ktx_uint32_t x, y;
|
||||
} blockCount;
|
||||
ktx_uint32_t blockSizeInBytes;
|
||||
ktx_uint32_t rowBytes;
|
||||
|
||||
assert (This != NULL);
|
||||
|
||||
float levelWidth = (float)(This->baseWidth >> level);
|
||||
float levelHeight = (float)(This->baseHeight >> level);
|
||||
// Round up to next whole block. We can't use KTX_PADN because some of
|
||||
// the block sizes are not powers of 2.
|
||||
blockCount.x
|
||||
= (ktx_uint32_t)ceilf(levelWidth / prtctd->_formatSize.blockWidth);
|
||||
blockCount.y
|
||||
= (ktx_uint32_t)ceilf(levelHeight / prtctd->_formatSize.blockHeight);
|
||||
blockCount.x = MAX(prtctd->_formatSize.minBlocksX, blockCount.x);
|
||||
blockCount.y = MAX(prtctd->_formatSize.minBlocksY, blockCount.y);
|
||||
|
||||
blockSizeInBytes = prtctd->_formatSize.blockSizeInBits / 8;
|
||||
|
||||
if (prtctd->_formatSize.flags & KTX_FORMAT_SIZE_COMPRESSED_BIT) {
|
||||
assert(This->isCompressed);
|
||||
return blockCount.x * blockCount.y * blockSizeInBytes;
|
||||
} else {
|
||||
assert(prtctd->_formatSize.blockWidth == 1U
|
||||
&& prtctd->_formatSize.blockHeight == 1U
|
||||
&& prtctd->_formatSize.blockDepth == 1U);
|
||||
rowBytes = blockCount.x * blockSizeInBytes;
|
||||
if (fv == KTX_FORMAT_VERSION_ONE)
|
||||
(void)padRow(&rowBytes);
|
||||
return rowBytes * blockCount.y;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @memberof ktxTexture
|
||||
* @~English
|
||||
* @brief Iterate over the levels or faces in a ktxTexture object.
|
||||
*
|
||||
* Blocks of image data are passed to an application-supplied callback
|
||||
* function. This is not a strict per-image iteration. Rather it reflects how
|
||||
* OpenGL needs the images. For most textures the block of data includes all
|
||||
* images of a mip level which implies all layers of an array. However, for
|
||||
* non-array cube map textures the block is a single face of the mip level,
|
||||
* i.e the callback is called once for each face.
|
||||
*
|
||||
* 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
|
||||
* externally.
|
||||
*
|
||||
* @param[in] This pointer to the ktxTexture object of interest.
|
||||
* @param[in,out] iterCb the address of a callback function which is called
|
||||
* with the data for each image block.
|
||||
* @param[in,out] userdata the address of application-specific data which is
|
||||
* passed to the callback along with the image data.
|
||||
*
|
||||
* @return KTX_SUCCESS on success, other KTX_* enum values on error. The
|
||||
* following are returned directly by this function. @p iterCb may
|
||||
* return these for other causes or may return additional errors.
|
||||
*
|
||||
* @exception KTX_FILE_DATA_ERROR Mip level sizes are increasing not
|
||||
* decreasing
|
||||
* @exception KTX_INVALID_VALUE @p This is @c NULL or @p iterCb is @c NULL.
|
||||
*
|
||||
*/
|
||||
KTX_error_code
|
||||
ktxTexture_IterateLevelFaces(ktxTexture* This, PFNKTXITERCB iterCb,
|
||||
void* userdata)
|
||||
{
|
||||
ktx_uint32_t miplevel;
|
||||
KTX_error_code result = KTX_SUCCESS;
|
||||
|
||||
if (This == NULL)
|
||||
return KTX_INVALID_VALUE;
|
||||
|
||||
if (iterCb == NULL)
|
||||
return KTX_INVALID_VALUE;
|
||||
|
||||
for (miplevel = 0; miplevel < This->numLevels; ++miplevel)
|
||||
{
|
||||
ktx_uint32_t faceLodSize;
|
||||
ktx_uint32_t face;
|
||||
ktx_uint32_t innerIterations;
|
||||
GLsizei width, height, depth;
|
||||
|
||||
/* Array textures have the same number of layers at each mip level. */
|
||||
width = MAX(1, This->baseWidth >> miplevel);
|
||||
height = MAX(1, This->baseHeight >> miplevel);
|
||||
depth = MAX(1, This->baseDepth >> miplevel);
|
||||
|
||||
faceLodSize = (ktx_uint32_t)ktxTexture_calcFaceLodSize(
|
||||
This, miplevel);
|
||||
|
||||
/* All array layers are passed in a group because that is how
|
||||
* GL & Vulkan need them. Hence no
|
||||
* for (layer = 0; layer < This->numLayers)
|
||||
*/
|
||||
if (This->isCubemap && !This->isArray)
|
||||
innerIterations = This->numFaces;
|
||||
else
|
||||
innerIterations = 1;
|
||||
for (face = 0; face < innerIterations; ++face)
|
||||
{
|
||||
/* And all z_slices are also passed as a group hence no
|
||||
* for (slice = 0; slice < This->depth)
|
||||
*/
|
||||
ktx_size_t offset;
|
||||
|
||||
ktxTexture_GetImageOffset(This, miplevel, 0, face, &offset);
|
||||
result = iterCb(miplevel, face,
|
||||
width, height, depth,
|
||||
faceLodSize, This->pData + offset, userdata);
|
||||
|
||||
if (result != KTX_SUCCESS)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
* @brief Calculate and apply the padding needed to comply with
|
||||
* KTX_GL_UNPACK_ALIGNMENT.
|
||||
*
|
||||
* For uncompressed textures, KTX format specifies KTX_GL_UNPACK_ALIGNMENT = 4.
|
||||
*
|
||||
* @param[in,out] rowBytes pointer to variable containing the packed no. of
|
||||
* bytes in a row. The no. of bytes after padding
|
||||
* is written into this location.
|
||||
* @return the no. of bytes of padding.
|
||||
*/
|
||||
static ktx_uint32_t
|
||||
padRow(ktx_uint32_t* rowBytes)
|
||||
{
|
||||
ktx_uint32_t rowPadding;
|
||||
|
||||
assert (rowBytes != NULL);
|
||||
|
||||
rowPadding = _KTX_PAD_UNPACK_ALIGN_LEN(*rowBytes);
|
||||
*rowBytes += rowPadding;
|
||||
return rowPadding;
|
||||
}
|
||||
|
||||
/**
|
||||
* @memberof ktxTexture @private
|
||||
* @~English
|
||||
* @brief Calculate the size of an array layer at the specified mip level.
|
||||
*
|
||||
* The size of a layer is the size of an image * either the number of faces
|
||||
* or the number of depth slices. This is the size of a layer as needed to
|
||||
* find the offset within the array of images of a level and layer so the size
|
||||
* reflects any @c cubePadding.
|
||||
*
|
||||
* @param[in] This pointer to the ktxTexture object of interest.
|
||||
* @param[in] level level whose layer size to return.
|
||||
*
|
||||
* @return the layer size in bytes.
|
||||
*/
|
||||
ktx_size_t
|
||||
ktxTexture_layerSize(ktxTexture* This, ktx_uint32_t level,
|
||||
ktxFormatVersionEnum fv)
|
||||
{
|
||||
/*
|
||||
* As there are no 3D cubemaps, the image's z block count will always be
|
||||
* 1 for cubemaps and numFaces will always be 1 for 3D textures so the
|
||||
* multiply is safe. 3D cubemaps, if they existed, would require
|
||||
* imageSize * (blockCount.z + This->numFaces);
|
||||
*/
|
||||
DECLARE_PROTECTED(ktxTexture);
|
||||
ktx_uint32_t blockCountZ;
|
||||
ktx_size_t imageSize, layerSize;
|
||||
|
||||
assert (This != NULL);
|
||||
assert (prtctd->_formatSize.blockDepth != 0);
|
||||
|
||||
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) {
|
||||
if (This->isCubemap && !This->isArray) {
|
||||
/* cubePadding. NOTE: this adds padding after the last face too. */
|
||||
layerSize += _KTX_PAD4(layerSize);
|
||||
}
|
||||
}
|
||||
return layerSize * This->numFaces;
|
||||
}
|
||||
|
||||
/**
|
||||
* @memberof ktxTexture @private
|
||||
* @~English
|
||||
* @brief Calculate the size of the specified mip level.
|
||||
*
|
||||
* The size of a level is the size of a layer * the number of layers.
|
||||
*
|
||||
* @param[in] This pointer to the ktxTexture object of interest.
|
||||
* @param[in] level level whose layer size to return.
|
||||
*
|
||||
* @return the level size in bytes.
|
||||
*/
|
||||
ktx_size_t
|
||||
ktxTexture_calcLevelSize(ktxTexture* This, ktx_uint32_t level,
|
||||
ktxFormatVersionEnum fv)
|
||||
{
|
||||
assert (This != NULL);
|
||||
assert (level < This->numLevels);
|
||||
return ktxTexture_layerSize(This, level, fv) * This->numLayers;
|
||||
}
|
||||
|
||||
/**
|
||||
* @memberof ktxTexture @private
|
||||
* @~English
|
||||
* @brief Calculate the faceLodSize of the specified mip level.
|
||||
*
|
||||
* The faceLodSize of a level for most textures is the size of a level. For
|
||||
* non-array cube map textures is the size of a face. This is the size that
|
||||
* must be provided to OpenGL when uploading textures. Faces get uploaded 1
|
||||
* at a time while all layers of an array or all slices of a 3D texture are
|
||||
* uploaded together.
|
||||
*
|
||||
* @param[in] This pointer to the ktxTexture object of interest.
|
||||
* @param[in] level level whose layer size to return.
|
||||
*
|
||||
* @return the faceLodSize size in bytes.
|
||||
*/
|
||||
ktx_size_t
|
||||
ktxTexture_doCalcFaceLodSize(ktxTexture* This, ktx_uint32_t level,
|
||||
ktxFormatVersionEnum fv)
|
||||
{
|
||||
/*
|
||||
* For non-array cubemaps this is the size of a face. For everything
|
||||
* else it is the size of the level.
|
||||
*/
|
||||
if (This->isCubemap && !This->isArray)
|
||||
return ktxTexture_calcImageSize(This, level, fv);
|
||||
else
|
||||
return ktxTexture_calcLevelSize(This, level, fv);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @memberof ktxTexture @private
|
||||
* @~English
|
||||
* @brief Return the number of bytes needed to store all the image data for
|
||||
* a ktxTexture.
|
||||
*
|
||||
* The caclulated size does not include space for storing the @c imageSize
|
||||
* fields of each mip level.
|
||||
*
|
||||
* @param[in] This pointer to the ktxTexture object of interest.
|
||||
* @param[in] fv enum specifying format version for which to calculate
|
||||
* image size.
|
||||
*
|
||||
* @return the data size in bytes.
|
||||
*/
|
||||
ktx_size_t
|
||||
ktxTexture_calcDataSizeTexture(ktxTexture* This)
|
||||
{
|
||||
assert (This != NULL);
|
||||
return ktxTexture_calcDataSizeLevels(This, This->numLevels);
|
||||
}
|
||||
|
||||
/**
|
||||
* @memberof ktxTexture @private
|
||||
* @~English
|
||||
* @brief Get information about rows of an uncompresssed texture image at a
|
||||
* specified level.
|
||||
*
|
||||
* For an image at @p level of a ktxTexture provide the number of rows, the
|
||||
* packed (unpadded) number of bytes in a row and the padding necessary to
|
||||
* comply with KTX_GL_UNPACK_ALIGNMENT.
|
||||
*
|
||||
* @param[in] This pointer to the ktxTexture object of interest.
|
||||
* @param[in] level level of interest.
|
||||
* @param[in,out] numRows pointer to location to store the number of rows.
|
||||
* @param[in,out] pRowLengthBytes pointer to location to store number of bytes
|
||||
* in a row.
|
||||
* @param[in.out] pRowPadding pointer to location to store the number of bytes
|
||||
* of padding.
|
||||
*/
|
||||
void
|
||||
ktxTexture_rowInfo(ktxTexture* This, ktx_uint32_t level,
|
||||
ktx_uint32_t* numRows, ktx_uint32_t* pRowLengthBytes,
|
||||
ktx_uint32_t* pRowPadding)
|
||||
{
|
||||
DECLARE_PROTECTED(ktxTexture);
|
||||
struct blockCount {
|
||||
ktx_uint32_t x;
|
||||
} blockCount;
|
||||
|
||||
assert (This != NULL);
|
||||
|
||||
assert(!This->isCompressed);
|
||||
assert(prtctd->_formatSize.blockWidth == 1U
|
||||
&& prtctd->_formatSize.blockHeight == 1U
|
||||
&& prtctd->_formatSize.blockDepth == 1U);
|
||||
|
||||
blockCount.x = MAX(1, (This->baseWidth / prtctd->_formatSize.blockWidth) >> level);
|
||||
*numRows = MAX(1, (This->baseHeight / prtctd->_formatSize.blockHeight) >> level);
|
||||
|
||||
*pRowLengthBytes = blockCount.x * prtctd->_formatSize.blockSizeInBits / 8;
|
||||
*pRowPadding = padRow(pRowLengthBytes);
|
||||
}
|
||||
|
||||
/**
|
||||
* @memberof ktxTexture
|
||||
* @~English
|
||||
* @brief Return pitch between rows of a texture image level in bytes.
|
||||
*
|
||||
* For uncompressed textures the pitch is the number of bytes between
|
||||
* rows of texels. For compressed textures it is the number of bytes
|
||||
* between rows of blocks. The value is padded to GL_UNPACK_ALIGNMENT,
|
||||
* if necessary. For all currently known compressed formats padding
|
||||
* will not be necessary.
|
||||
*
|
||||
* @param[in] This pointer to the ktxTexture object of interest.
|
||||
* @param[in] level level of interest.
|
||||
*
|
||||
* @return the row pitch in bytes.
|
||||
*/
|
||||
ktx_uint32_t
|
||||
ktxTexture_GetRowPitch(ktxTexture* This, ktx_uint32_t level)
|
||||
{
|
||||
DECLARE_PROTECTED(ktxTexture)
|
||||
struct blockCount {
|
||||
ktx_uint32_t x;
|
||||
} blockCount;
|
||||
ktx_uint32_t pitch;
|
||||
|
||||
blockCount.x = MAX(1, (This->baseWidth / prtctd->_formatSize.blockWidth) >> level);
|
||||
pitch = blockCount.x * prtctd->_formatSize.blockSizeInBits / 8;
|
||||
(void)padRow(&pitch);
|
||||
|
||||
return pitch;
|
||||
}
|
||||
|
||||
/**
|
||||
* @memberof ktxTexture @private
|
||||
* @~English
|
||||
* @brief Query if a ktxTexture has an active stream.
|
||||
*
|
||||
* Tests if a ktxTexture has unread image data. The internal stream is closed
|
||||
* once all the images have been read.
|
||||
*
|
||||
* @param[in] This pointer to the ktxTexture object of interest.
|
||||
*
|
||||
* @return KTX_TRUE if there is an active stream, KTX_FALSE otherwise.
|
||||
*/
|
||||
ktx_bool_t
|
||||
ktxTexture_isActiveStream(ktxTexture* This)
|
||||
{
|
||||
assert(This != NULL);
|
||||
ktxStream* stream = ktxTexture_getStream(This);
|
||||
return stream->data.file != NULL;
|
||||
}
|
||||
|
||||
/** @} */
|
||||
|
108
thirdparty/libktx/lib/texture.h
vendored
Normal file
108
thirdparty/libktx/lib/texture.h
vendored
Normal file
@@ -0,0 +1,108 @@
|
||||
/* -*- tab-width: 4; -*- */
|
||||
/* vi: set sw=2 ts=4 expandtab textwidth=70: */
|
||||
|
||||
/*
|
||||
* Copyright 2019-2020 The Khronos Group Inc.
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
/**
|
||||
* @internal
|
||||
* @file
|
||||
* @~English
|
||||
*
|
||||
* @brief Declare internal ktxTexture functions for sharing between
|
||||
* compilation units.
|
||||
*
|
||||
* These functions are private and should not be used outside the library.
|
||||
*/
|
||||
|
||||
#ifndef _TEXTURE_H_
|
||||
#define _TEXTURE_H_
|
||||
|
||||
#include "ktx.h"
|
||||
#include "formatsize.h"
|
||||
|
||||
#define DECLARE_PRIVATE(class) class ## _private* private = This->_private
|
||||
#define DECLARE_PROTECTED(class) class ## _protected* prtctd = This->_protected;
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef enum {
|
||||
KTX_FORMAT_VERSION_ONE = 1,
|
||||
KTX_FORMAT_VERSION_TWO = 2
|
||||
} ktxFormatVersionEnum;
|
||||
|
||||
typedef ktx_size_t (* PFNCALCDATASIZELEVELS)(ktxTexture* This,
|
||||
ktx_uint32_t levels);
|
||||
typedef ktx_size_t (* PFNCALCFACELODSIZE)(ktxTexture* This, ktx_uint32_t level);
|
||||
typedef ktx_size_t (* PFNCALCLEVELOFFSET)(ktxTexture* This, ktx_uint32_t level);
|
||||
typedef struct ktxTexture_vtblInt {
|
||||
PFNCALCDATASIZELEVELS calcDataSizeLevels;
|
||||
PFNCALCFACELODSIZE calcFaceLodSize;
|
||||
PFNCALCLEVELOFFSET calcLevelOffset;
|
||||
} ktxTexture_vtblInt;
|
||||
|
||||
#define ktxTexture_calcDataSizeLevels(This, levels) \
|
||||
This->_protected->_vtbl.calcDataSizeLevels(This, levels);
|
||||
#define ktxTexture_calcFaceLodSize(This, level) \
|
||||
This->_protected->_vtbl.calcFaceLodSize(This, level);
|
||||
#define ktxTexture_calcLevelOffset(This, level) \
|
||||
This->_protected->_vtbl.calcLevelOffset(This, level);
|
||||
|
||||
/**
|
||||
* @memberof ktxTexture
|
||||
* @~English
|
||||
*
|
||||
* @brief protected members of ktxTexture.
|
||||
*/
|
||||
typedef struct ktxTexture_protected {
|
||||
ktxTexture_vtblInt _vtbl;
|
||||
ktxFormatSize _formatSize;
|
||||
ktx_uint32_t _typeSize;
|
||||
ktxStream _stream;
|
||||
} ktxTexture_protected;
|
||||
|
||||
#define ktxTexture_getStream(t) ((ktxStream*)(&(t)->_protected->_stream))
|
||||
#define ktxTexture1_getStream(t1) ktxTexture_getStream((ktxTexture*)t1)
|
||||
#define ktxTexture2_getStream(t2) ktxTexture_getStream((ktxTexture*)t2)
|
||||
|
||||
KTX_error_code
|
||||
ktxTexture_iterateLoadedImages(ktxTexture* This, PFNKTXITERCB iterCb,
|
||||
void* userdata);
|
||||
KTX_error_code
|
||||
ktxTexture_iterateSourceImages(ktxTexture* This, PFNKTXITERCB iterCb,
|
||||
void* userdata);
|
||||
|
||||
ktx_size_t ktxTexture_calcDataSizeTexture(ktxTexture* This);
|
||||
ktx_size_t ktxTexture_calcImageSize(ktxTexture* This, ktx_uint32_t level,
|
||||
ktxFormatVersionEnum fv);
|
||||
ktx_bool_t ktxTexture_isActiveStream(ktxTexture* This);
|
||||
ktx_size_t ktxTexture_calcLevelSize(ktxTexture* This, ktx_uint32_t level,
|
||||
ktxFormatVersionEnum fv);
|
||||
ktx_size_t ktxTexture_doCalcFaceLodSize(ktxTexture* This, ktx_uint32_t level,
|
||||
ktxFormatVersionEnum fv);
|
||||
ktx_size_t ktxTexture_layerSize(ktxTexture* This, ktx_uint32_t level,
|
||||
ktxFormatVersionEnum fv);
|
||||
void ktxTexture_rowInfo(ktxTexture* This, ktx_uint32_t level,
|
||||
ktx_uint32_t* numRows, ktx_uint32_t* rowBytes,
|
||||
ktx_uint32_t* rowPadding);
|
||||
KTX_error_code
|
||||
ktxTexture_construct(ktxTexture* This,
|
||||
const ktxTextureCreateInfo* const createInfo,
|
||||
ktxFormatSize* formatSize);
|
||||
|
||||
KTX_error_code
|
||||
ktxTexture_constructFromStream(ktxTexture* This, ktxStream* pStream,
|
||||
ktxTextureCreateFlags createFlags);
|
||||
|
||||
void
|
||||
ktxTexture_destruct(ktxTexture* This);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _TEXTURE_H_ */
|
1494
thirdparty/libktx/lib/texture1.c
vendored
Normal file
1494
thirdparty/libktx/lib/texture1.c
vendored
Normal file
File diff suppressed because it is too large
Load Diff
46
thirdparty/libktx/lib/texture1.h
vendored
Normal file
46
thirdparty/libktx/lib/texture1.h
vendored
Normal file
@@ -0,0 +1,46 @@
|
||||
/* -*- tab-width: 4; -*- */
|
||||
/* vi: set sw=2 ts=4 expandtab textwidth=70: */
|
||||
|
||||
/*
|
||||
* Copyright 2019-2020 The Khronos Group Inc.
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
/**
|
||||
* @internal
|
||||
* @file
|
||||
* @~English
|
||||
*
|
||||
* @brief Declare internal ktxTexture1 functions for sharing between
|
||||
* compilation units.
|
||||
*
|
||||
* These functions are private and should not be used outside the library.
|
||||
*/
|
||||
|
||||
#ifndef _TEXTURE1_H_
|
||||
#define _TEXTURE1_H_
|
||||
|
||||
#include "texture.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define CLASS ktxTexture1
|
||||
#include "texture_funcs.inl"
|
||||
#undef CLASS
|
||||
|
||||
KTX_error_code
|
||||
ktxTexture1_constructFromStreamAndHeader(ktxTexture1* This, ktxStream* pStream,
|
||||
KTX_header* pHeader,
|
||||
ktxTextureCreateFlags createFlags);
|
||||
|
||||
ktx_uint64_t ktxTexture1_calcDataSizeTexture(ktxTexture1* This);
|
||||
ktx_size_t ktxTexture1_calcLevelOffset(ktxTexture1* This, ktx_uint32_t level);
|
||||
ktx_uint32_t ktxTexture1_glTypeSize(ktxTexture1* This);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _TEXTURE1_H_ */
|
3028
thirdparty/libktx/lib/texture2.c
vendored
Normal file
3028
thirdparty/libktx/lib/texture2.c
vendored
Normal file
File diff suppressed because it is too large
Load Diff
67
thirdparty/libktx/lib/texture2.h
vendored
Normal file
67
thirdparty/libktx/lib/texture2.h
vendored
Normal file
@@ -0,0 +1,67 @@
|
||||
/* -*- tab-width: 4; -*- */
|
||||
/* vi: set sw=2 ts=4 expandtab textwidth=70: */
|
||||
|
||||
/*
|
||||
* Copyright 2019-2020 The Khronos Group Inc.
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
/**
|
||||
* @internal
|
||||
* @file
|
||||
* @~English
|
||||
*
|
||||
* @brief Declare internal ktxTexture2 functions for sharing between
|
||||
* compilation units.
|
||||
*
|
||||
* These functions are private and should not be used outside the library.
|
||||
*/
|
||||
|
||||
#ifndef _TEXTURE2_H_
|
||||
#define _TEXTURE2_H_
|
||||
|
||||
#include "texture.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define CLASS ktxTexture2
|
||||
#include "texture_funcs.inl"
|
||||
#undef CLASS
|
||||
|
||||
typedef struct ktxTexture2_private {
|
||||
ktx_uint8_t* _supercompressionGlobalData;
|
||||
ktx_uint32_t _requiredLevelAlignment;
|
||||
ktx_uint64_t _sgdByteLength;
|
||||
ktx_uint64_t _firstLevelFileOffset; /*!< Always 0, unless the texture was
|
||||
created from a stream and the image
|
||||
data is not yet loaded. */
|
||||
// Must be last so it can grow.
|
||||
ktxLevelIndexEntry _levelIndex[1]; /*!< Offsets in this index are from the
|
||||
start of the image data. Use
|
||||
ktxTexture_levelStreamOffset() and
|
||||
ktxTexture_levelDataOffset(). The former
|
||||
will add the above file offset to the
|
||||
index offset. */
|
||||
} ktxTexture2_private;
|
||||
|
||||
|
||||
KTX_error_code
|
||||
ktxTexture2_constructCopy(ktxTexture2* This, ktxTexture2* orig);
|
||||
KTX_error_code
|
||||
ktxTexture2_constructFromStreamAndHeader(ktxTexture2* This, ktxStream* pStream,
|
||||
KTX_header2* pHeader,
|
||||
ktxTextureCreateFlags createFlags);
|
||||
|
||||
ktx_uint64_t ktxTexture2_calcDataSizeTexture(ktxTexture2* This);
|
||||
ktx_size_t ktxTexture2_calcLevelOffset(ktxTexture2* This, ktx_uint32_t level);
|
||||
ktx_uint32_t ktxTexture2_calcRequiredLevelAlignment(ktxTexture2* This);
|
||||
ktx_uint64_t ktxTexture2_levelFileOffset(ktxTexture2* This, ktx_uint32_t level);
|
||||
ktx_uint64_t ktxTexture2_levelDataOffset(ktxTexture2* This, ktx_uint32_t level);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _TEXTURE2_H_ */
|
61
thirdparty/libktx/lib/texture_funcs.inl
vendored
Normal file
61
thirdparty/libktx/lib/texture_funcs.inl
vendored
Normal file
@@ -0,0 +1,61 @@
|
||||
/* -*- tab-width: 4; -*- */
|
||||
/* vi: set sw=2 ts=4 expandtab textwidth=70: */
|
||||
|
||||
/*
|
||||
* Copyright 2019-2020 The Khronos Group Inc.
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
/**
|
||||
* @internal
|
||||
* @file
|
||||
* @~English
|
||||
*
|
||||
* @brief Templates for functions common to base & derived ktxTexture classes.
|
||||
*
|
||||
* Define CLASS before including this file.
|
||||
*/
|
||||
|
||||
#define CAT(c, n) PRIMITIVE_CAT(c, n)
|
||||
#define PRIMITIVE_CAT(c, n) c ## _ ## n
|
||||
|
||||
#define CLASS_FUNC(name) CAT(CLASS, name)
|
||||
|
||||
/*
|
||||
======================================
|
||||
Virtual ktxTexture functions
|
||||
======================================
|
||||
*/
|
||||
|
||||
|
||||
ktx_size_t CLASS_FUNC(GetImageSize)(CLASS* This, ktx_uint32_t level);
|
||||
KTX_error_code CLASS_FUNC(GLUpload)(CLASS* This, GLuint* pTexture,
|
||||
GLenum* pTarget, GLenum* pGlerror);
|
||||
KTX_error_code CLASS_FUNC(IterateLevels)(CLASS* This,
|
||||
PFNKTXITERCB iterCb,
|
||||
void* userdata);
|
||||
KTX_error_code CLASS_FUNC(IterateLevelFaces)(CLASS* This,
|
||||
PFNKTXITERCB iterCb,
|
||||
void* userdata);
|
||||
KTX_error_code CLASS_FUNC(IterateLoadLevelFaces)(CLASS* This,
|
||||
PFNKTXITERCB iterCb,
|
||||
void* userdata);
|
||||
KTX_error_code CLASS_FUNC(SetImageFromStdioStream)(CLASS* This,
|
||||
ktx_uint32_t level,ktx_uint32_t layer,
|
||||
ktx_uint32_t faceSlice,
|
||||
FILE* src, ktx_size_t srcSize);
|
||||
KTX_error_code CLASS_FUNC(SetImageFromMemory)(CLASS* This,
|
||||
ktx_uint32_t level, ktx_uint32_t layer,
|
||||
ktx_uint32_t faceSlice,
|
||||
const ktx_uint8_t* src, ktx_size_t srcSize);
|
||||
|
||||
|
||||
/*
|
||||
======================================
|
||||
Internal ktxTexture functions
|
||||
======================================
|
||||
*/
|
||||
|
||||
|
||||
void CLASS_FUNC(destruct)(CLASS* This);
|
||||
|
942
thirdparty/libktx/lib/uthash.h
vendored
Normal file
942
thirdparty/libktx/lib/uthash.h
vendored
Normal file
@@ -0,0 +1,942 @@
|
||||
/*
|
||||
Copyright (c) 2003-2010, Troy D. Hanson http://uthash.sourceforge.net All rights reserved.
|
||||
SPDX-License-Identifier: BSD-1-Clause
|
||||
*/
|
||||
|
||||
#ifndef UTHASH_H
|
||||
#define UTHASH_H
|
||||
|
||||
#include <string.h> /* memcmp,strlen */
|
||||
#include <stddef.h> /* ptrdiff_t */
|
||||
|
||||
/* These macros use decltype or the earlier __typeof GNU extension.
|
||||
As decltype is only available in newer compilers (VS2010 or gcc 4.3+
|
||||
when compiling c++ source) this code uses whatever method is needed
|
||||
or, for VS2008 where neither is available, uses casting workarounds. */
|
||||
#ifdef _MSC_VER /* MS compiler */
|
||||
#if _MSC_VER >= 1600 && __cplusplus /* VS2010 or newer in C++ mode */
|
||||
#define DECLTYPE(x) (decltype(x))
|
||||
#else /* VS2008 or older (or VS2010 in C mode) */
|
||||
#define NO_DECLTYPE
|
||||
#define DECLTYPE(x)
|
||||
#endif
|
||||
#else /* GNU, Sun and other compilers */
|
||||
#define DECLTYPE(x) (__typeof(x))
|
||||
#endif
|
||||
|
||||
#ifdef NO_DECLTYPE
|
||||
#define DECLTYPE_ASSIGN(dst,src) \
|
||||
do { \
|
||||
char **_da_dst = (char**)(&(dst)); \
|
||||
*_da_dst = (char*)(src); \
|
||||
} while(0)
|
||||
#else
|
||||
#define DECLTYPE_ASSIGN(dst,src) \
|
||||
do { \
|
||||
(dst) = DECLTYPE(dst)(src); \
|
||||
} while(0)
|
||||
#endif
|
||||
|
||||
/* a number of the hash function use uint32_t which isn't defined on win32 */
|
||||
#ifdef _MSC_VER
|
||||
typedef unsigned int uint32_t;
|
||||
#else
|
||||
#include <inttypes.h> /* uint32_t */
|
||||
#endif
|
||||
|
||||
#define UTHASH_VERSION 1.9.1
|
||||
|
||||
#define uthash_fatal(msg) exit(-1) /* fatal error (out of memory,etc) */
|
||||
#define uthash_malloc(sz) malloc(sz) /* malloc fcn */
|
||||
#define uthash_free(ptr) free(ptr) /* free fcn */
|
||||
|
||||
#define uthash_noexpand_fyi(tbl) /* can be defined to log noexpand */
|
||||
#define uthash_expand_fyi(tbl) /* can be defined to log expands */
|
||||
|
||||
/* initial number of buckets */
|
||||
#define HASH_INITIAL_NUM_BUCKETS 32 /* initial number of buckets */
|
||||
#define HASH_INITIAL_NUM_BUCKETS_LOG2 5 /* lg2 of initial number of buckets */
|
||||
#define HASH_BKT_CAPACITY_THRESH 10 /* expand when bucket count reaches */
|
||||
|
||||
/* calculate the element whose hash handle address is hhe */
|
||||
#define ELMT_FROM_HH(tbl,hhp) ((void*)(((char*)(hhp)) - ((tbl)->hho)))
|
||||
|
||||
#define HASH_FIND(hh,head,keyptr,keylen,out) \
|
||||
do { \
|
||||
unsigned _hf_bkt,_hf_hashv; \
|
||||
out=NULL; \
|
||||
if (head) { \
|
||||
HASH_FCN(keyptr,keylen, (head)->hh.tbl->num_buckets, _hf_hashv, _hf_bkt); \
|
||||
if (HASH_BLOOM_TEST((head)->hh.tbl, _hf_hashv)) { \
|
||||
HASH_FIND_IN_BKT((head)->hh.tbl, hh, (head)->hh.tbl->buckets[ _hf_bkt ], \
|
||||
keyptr,keylen,out); \
|
||||
} \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#ifdef HASH_BLOOM
|
||||
#define HASH_BLOOM_BITLEN (1ULL << HASH_BLOOM)
|
||||
#define HASH_BLOOM_BYTELEN (HASH_BLOOM_BITLEN/8) + ((HASH_BLOOM_BITLEN%8) ? 1:0)
|
||||
#define HASH_BLOOM_MAKE(tbl) \
|
||||
do { \
|
||||
(tbl)->bloom_nbits = HASH_BLOOM; \
|
||||
(tbl)->bloom_bv = (uint8_t*)uthash_malloc(HASH_BLOOM_BYTELEN); \
|
||||
if (!((tbl)->bloom_bv)) { uthash_fatal( "out of memory"); } \
|
||||
memset((tbl)->bloom_bv, 0, HASH_BLOOM_BYTELEN); \
|
||||
(tbl)->bloom_sig = HASH_BLOOM_SIGNATURE; \
|
||||
} while (0);
|
||||
|
||||
#define HASH_BLOOM_FREE(tbl) \
|
||||
do { \
|
||||
uthash_free((tbl)->bloom_bv); \
|
||||
} while (0);
|
||||
|
||||
#define HASH_BLOOM_BITSET(bv,idx) (bv[(idx)/8] |= (1U << ((idx)%8)))
|
||||
#define HASH_BLOOM_BITTEST(bv,idx) (bv[(idx)/8] & (1U << ((idx)%8)))
|
||||
|
||||
#define HASH_BLOOM_ADD(tbl,hashv) \
|
||||
HASH_BLOOM_BITSET((tbl)->bloom_bv, (hashv & (uint32_t)((1ULL << (tbl)->bloom_nbits) - 1)))
|
||||
|
||||
#define HASH_BLOOM_TEST(tbl,hashv) \
|
||||
HASH_BLOOM_BITTEST((tbl)->bloom_bv, (hashv & (uint32_t)((1ULL << (tbl)->bloom_nbits) - 1)))
|
||||
|
||||
#else
|
||||
#define HASH_BLOOM_MAKE(tbl)
|
||||
#define HASH_BLOOM_FREE(tbl)
|
||||
#define HASH_BLOOM_ADD(tbl,hashv)
|
||||
#define HASH_BLOOM_TEST(tbl,hashv) (1)
|
||||
#endif
|
||||
|
||||
#define HASH_MAKE_TABLE(hh,head) \
|
||||
do { \
|
||||
(head)->hh.tbl = (UT_hash_table*)uthash_malloc( \
|
||||
sizeof(UT_hash_table)); \
|
||||
if (!((head)->hh.tbl)) { uthash_fatal( "out of memory"); } \
|
||||
memset((head)->hh.tbl, 0, sizeof(UT_hash_table)); \
|
||||
(head)->hh.tbl->tail = &((head)->hh); \
|
||||
(head)->hh.tbl->num_buckets = HASH_INITIAL_NUM_BUCKETS; \
|
||||
(head)->hh.tbl->log2_num_buckets = HASH_INITIAL_NUM_BUCKETS_LOG2; \
|
||||
(head)->hh.tbl->hho = (char*)(&(head)->hh) - (char*)(head); \
|
||||
(head)->hh.tbl->buckets = (UT_hash_bucket*)uthash_malloc( \
|
||||
HASH_INITIAL_NUM_BUCKETS*sizeof(struct UT_hash_bucket)); \
|
||||
if (! (head)->hh.tbl->buckets) { uthash_fatal( "out of memory"); } \
|
||||
memset((head)->hh.tbl->buckets, 0, \
|
||||
HASH_INITIAL_NUM_BUCKETS*sizeof(struct UT_hash_bucket)); \
|
||||
HASH_BLOOM_MAKE((head)->hh.tbl); \
|
||||
(head)->hh.tbl->signature = HASH_SIGNATURE; \
|
||||
} while(0)
|
||||
|
||||
#define HASH_ADD(hh,head,fieldname,keylen_in,add) \
|
||||
HASH_ADD_KEYPTR(hh,head,&add->fieldname,keylen_in,add)
|
||||
|
||||
#define HASH_ADD_KEYPTR(hh,head,keyptr,keylen_in,add) \
|
||||
do { \
|
||||
unsigned _ha_bkt; \
|
||||
(add)->hh.next = NULL; \
|
||||
(add)->hh.key = (char*)keyptr; \
|
||||
(add)->hh.keylen = keylen_in; \
|
||||
if (!(head)) { \
|
||||
head = (add); \
|
||||
(head)->hh.prev = NULL; \
|
||||
HASH_MAKE_TABLE(hh,head); \
|
||||
} else { \
|
||||
(head)->hh.tbl->tail->next = (add); \
|
||||
(add)->hh.prev = ELMT_FROM_HH((head)->hh.tbl, (head)->hh.tbl->tail); \
|
||||
(head)->hh.tbl->tail = &((add)->hh); \
|
||||
} \
|
||||
(head)->hh.tbl->num_items++; \
|
||||
(add)->hh.tbl = (head)->hh.tbl; \
|
||||
HASH_FCN(keyptr,keylen_in, (head)->hh.tbl->num_buckets, \
|
||||
(add)->hh.hashv, _ha_bkt); \
|
||||
HASH_ADD_TO_BKT((head)->hh.tbl->buckets[_ha_bkt],&(add)->hh); \
|
||||
HASH_BLOOM_ADD((head)->hh.tbl,(add)->hh.hashv); \
|
||||
HASH_EMIT_KEY(hh,head,keyptr,keylen_in); \
|
||||
HASH_FSCK(hh,head); \
|
||||
} while(0)
|
||||
|
||||
#define HASH_TO_BKT( hashv, num_bkts, bkt ) \
|
||||
do { \
|
||||
bkt = ((hashv) & ((num_bkts) - 1)); \
|
||||
} while(0)
|
||||
|
||||
/* delete "delptr" from the hash table.
|
||||
* "the usual" patch-up process for the app-order doubly-linked-list.
|
||||
* The use of _hd_hh_del below deserves special explanation.
|
||||
* These used to be expressed using (delptr) but that led to a bug
|
||||
* if someone used the same symbol for the head and deletee, like
|
||||
* HASH_DELETE(hh,users,users);
|
||||
* We want that to work, but by changing the head (users) below
|
||||
* we were forfeiting our ability to further refer to the deletee (users)
|
||||
* in the patch-up process. Solution: use scratch space to
|
||||
* copy the deletee pointer, then the latter references are via that
|
||||
* scratch pointer rather than through the repointed (users) symbol.
|
||||
*/
|
||||
#define HASH_DELETE(hh,head,delptr) \
|
||||
do { \
|
||||
unsigned _hd_bkt; \
|
||||
struct UT_hash_handle *_hd_hh_del; \
|
||||
if ( ((delptr)->hh.prev == NULL) && ((delptr)->hh.next == NULL) ) { \
|
||||
uthash_free((head)->hh.tbl->buckets ); \
|
||||
HASH_BLOOM_FREE((head)->hh.tbl); \
|
||||
uthash_free((head)->hh.tbl); \
|
||||
head = NULL; \
|
||||
} else { \
|
||||
_hd_hh_del = &((delptr)->hh); \
|
||||
if ((delptr) == ELMT_FROM_HH((head)->hh.tbl,(head)->hh.tbl->tail)) { \
|
||||
(head)->hh.tbl->tail = \
|
||||
(UT_hash_handle*)((char*)((delptr)->hh.prev) + \
|
||||
(head)->hh.tbl->hho); \
|
||||
} \
|
||||
if ((delptr)->hh.prev) { \
|
||||
((UT_hash_handle*)((char*)((delptr)->hh.prev) + \
|
||||
(head)->hh.tbl->hho))->next = (delptr)->hh.next; \
|
||||
} else { \
|
||||
DECLTYPE_ASSIGN(head,(delptr)->hh.next); \
|
||||
} \
|
||||
if (_hd_hh_del->next) { \
|
||||
((UT_hash_handle*)((char*)_hd_hh_del->next + \
|
||||
(head)->hh.tbl->hho))->prev = \
|
||||
_hd_hh_del->prev; \
|
||||
} \
|
||||
HASH_TO_BKT( _hd_hh_del->hashv, (head)->hh.tbl->num_buckets, _hd_bkt); \
|
||||
HASH_DEL_IN_BKT(hh,(head)->hh.tbl->buckets[_hd_bkt], _hd_hh_del); \
|
||||
(head)->hh.tbl->num_items--; \
|
||||
} \
|
||||
HASH_FSCK(hh,head); \
|
||||
} while (0)
|
||||
|
||||
|
||||
/* convenience forms of HASH_FIND/HASH_ADD/HASH_DEL */
|
||||
#define HASH_FIND_STR(head,findstr,out) \
|
||||
HASH_FIND(hh,head,findstr,strlen(findstr),out)
|
||||
#define HASH_ADD_STR(head,strfield,add) \
|
||||
HASH_ADD(hh,head,strfield,strlen(add->strfield),add)
|
||||
#define HASH_FIND_INT(head,findint,out) \
|
||||
HASH_FIND(hh,head,findint,sizeof(int),out)
|
||||
#define HASH_ADD_INT(head,intfield,add) \
|
||||
HASH_ADD(hh,head,intfield,sizeof(int),add)
|
||||
#define HASH_FIND_PTR(head,findptr,out) \
|
||||
HASH_FIND(hh,head,findptr,sizeof(void *),out)
|
||||
#define HASH_ADD_PTR(head,ptrfield,add) \
|
||||
HASH_ADD(hh,head,ptrfield,sizeof(void *),add)
|
||||
#define HASH_DEL(head,delptr) \
|
||||
HASH_DELETE(hh,head,delptr)
|
||||
|
||||
/* HASH_FSCK checks hash integrity on every add/delete when HASH_DEBUG is defined.
|
||||
* This is for uthash developer only; it compiles away if HASH_DEBUG isn't defined.
|
||||
*/
|
||||
#ifdef HASH_DEBUG
|
||||
#define HASH_OOPS(...) do { fprintf(stderr,__VA_ARGS__); exit(-1); } while (0)
|
||||
#define HASH_FSCK(hh,head) \
|
||||
do { \
|
||||
unsigned _bkt_i; \
|
||||
unsigned _count, _bkt_count; \
|
||||
char *_prev; \
|
||||
struct UT_hash_handle *_thh; \
|
||||
if (head) { \
|
||||
_count = 0; \
|
||||
for( _bkt_i = 0; _bkt_i < (head)->hh.tbl->num_buckets; _bkt_i++) { \
|
||||
_bkt_count = 0; \
|
||||
_thh = (head)->hh.tbl->buckets[_bkt_i].hh_head; \
|
||||
_prev = NULL; \
|
||||
while (_thh) { \
|
||||
if (_prev != (char*)(_thh->hh_prev)) { \
|
||||
HASH_OOPS("invalid hh_prev %p, actual %p\n", \
|
||||
_thh->hh_prev, _prev ); \
|
||||
} \
|
||||
_bkt_count++; \
|
||||
_prev = (char*)(_thh); \
|
||||
_thh = _thh->hh_next; \
|
||||
} \
|
||||
_count += _bkt_count; \
|
||||
if ((head)->hh.tbl->buckets[_bkt_i].count != _bkt_count) { \
|
||||
HASH_OOPS("invalid bucket count %d, actual %d\n", \
|
||||
(head)->hh.tbl->buckets[_bkt_i].count, _bkt_count); \
|
||||
} \
|
||||
} \
|
||||
if (_count != (head)->hh.tbl->num_items) { \
|
||||
HASH_OOPS("invalid hh item count %d, actual %d\n", \
|
||||
(head)->hh.tbl->num_items, _count ); \
|
||||
} \
|
||||
/* traverse hh in app order; check next/prev integrity, count */ \
|
||||
_count = 0; \
|
||||
_prev = NULL; \
|
||||
_thh = &(head)->hh; \
|
||||
while (_thh) { \
|
||||
_count++; \
|
||||
if (_prev !=(char*)(_thh->prev)) { \
|
||||
HASH_OOPS("invalid prev %p, actual %p\n", \
|
||||
_thh->prev, _prev ); \
|
||||
} \
|
||||
_prev = (char*)ELMT_FROM_HH((head)->hh.tbl, _thh); \
|
||||
_thh = ( _thh->next ? (UT_hash_handle*)((char*)(_thh->next) + \
|
||||
(head)->hh.tbl->hho) : NULL ); \
|
||||
} \
|
||||
if (_count != (head)->hh.tbl->num_items) { \
|
||||
HASH_OOPS("invalid app item count %d, actual %d\n", \
|
||||
(head)->hh.tbl->num_items, _count ); \
|
||||
} \
|
||||
} \
|
||||
} while (0)
|
||||
#else
|
||||
#define HASH_FSCK(hh,head)
|
||||
#endif
|
||||
|
||||
/* When compiled with -DHASH_EMIT_KEYS, length-prefixed keys are emitted to
|
||||
* the descriptor to which this macro is defined for tuning the hash function.
|
||||
* The app can #include <unistd.h> to get the prototype for write(2). */
|
||||
#ifdef HASH_EMIT_KEYS
|
||||
#define HASH_EMIT_KEY(hh,head,keyptr,fieldlen) \
|
||||
do { \
|
||||
unsigned _klen = fieldlen; \
|
||||
write(HASH_EMIT_KEYS, &_klen, sizeof(_klen)); \
|
||||
write(HASH_EMIT_KEYS, keyptr, fieldlen); \
|
||||
} while (0)
|
||||
#else
|
||||
#define HASH_EMIT_KEY(hh,head,keyptr,fieldlen)
|
||||
#endif
|
||||
|
||||
/* default to Jenkin's hash unless overridden e.g. DHASH_FUNCTION=HASH_SAX */
|
||||
#ifdef HASH_FUNCTION
|
||||
#define HASH_FCN HASH_FUNCTION
|
||||
#else
|
||||
#define HASH_FCN HASH_JEN
|
||||
#endif
|
||||
|
||||
/* The Bernstein hash function, used in Perl prior to v5.6 */
|
||||
#define HASH_BER(key,keylen,num_bkts,hashv,bkt) \
|
||||
do { \
|
||||
unsigned _hb_keylen=keylen; \
|
||||
char *_hb_key=(char*)key; \
|
||||
(hashv) = 0; \
|
||||
while (_hb_keylen--) { (hashv) = ((hashv) * 33) + *_hb_key++; } \
|
||||
bkt = (hashv) & (num_bkts-1); \
|
||||
} while (0)
|
||||
|
||||
|
||||
/* SAX/FNV/OAT/JEN hash functions are macro variants of those listed at
|
||||
* http://eternallyconfuzzled.com/tuts/algorithms/jsw_tut_hashing.aspx */
|
||||
#define HASH_SAX(key,keylen,num_bkts,hashv,bkt) \
|
||||
do { \
|
||||
unsigned _sx_i; \
|
||||
char *_hs_key=(char*)key; \
|
||||
hashv = 0; \
|
||||
for(_sx_i=0; _sx_i < keylen; _sx_i++) \
|
||||
hashv ^= (hashv << 5) + (hashv >> 2) + _hs_key[_sx_i]; \
|
||||
bkt = hashv & (num_bkts-1); \
|
||||
} while (0)
|
||||
|
||||
#define HASH_FNV(key,keylen,num_bkts,hashv,bkt) \
|
||||
do { \
|
||||
unsigned _fn_i; \
|
||||
char *_hf_key=(char*)key; \
|
||||
hashv = 2166136261UL; \
|
||||
for(_fn_i=0; _fn_i < keylen; _fn_i++) \
|
||||
hashv = (hashv * 16777619) ^ _hf_key[_fn_i]; \
|
||||
bkt = hashv & (num_bkts-1); \
|
||||
} while(0);
|
||||
|
||||
#define HASH_OAT(key,keylen,num_bkts,hashv,bkt) \
|
||||
do { \
|
||||
unsigned _ho_i; \
|
||||
char *_ho_key=(char*)key; \
|
||||
hashv = 0; \
|
||||
for(_ho_i=0; _ho_i < keylen; _ho_i++) { \
|
||||
hashv += _ho_key[_ho_i]; \
|
||||
hashv += (hashv << 10); \
|
||||
hashv ^= (hashv >> 6); \
|
||||
} \
|
||||
hashv += (hashv << 3); \
|
||||
hashv ^= (hashv >> 11); \
|
||||
hashv += (hashv << 15); \
|
||||
bkt = hashv & (num_bkts-1); \
|
||||
} while(0)
|
||||
|
||||
#define HASH_JEN_MIX(a,b,c) \
|
||||
do { \
|
||||
a -= b; a -= c; a ^= ( c >> 13 ); \
|
||||
b -= c; b -= a; b ^= ( a << 8 ); \
|
||||
c -= a; c -= b; c ^= ( b >> 13 ); \
|
||||
a -= b; a -= c; a ^= ( c >> 12 ); \
|
||||
b -= c; b -= a; b ^= ( a << 16 ); \
|
||||
c -= a; c -= b; c ^= ( b >> 5 ); \
|
||||
a -= b; a -= c; a ^= ( c >> 3 ); \
|
||||
b -= c; b -= a; b ^= ( a << 10 ); \
|
||||
c -= a; c -= b; c ^= ( b >> 15 ); \
|
||||
} while (0)
|
||||
|
||||
#define HASH_JEN(key,keylen,num_bkts,hashv,bkt) \
|
||||
do { \
|
||||
unsigned _hj_i,_hj_j,_hj_k; \
|
||||
char *_hj_key=(char*)key; \
|
||||
hashv = 0xfeedbeef; \
|
||||
_hj_i = _hj_j = 0x9e3779b9; \
|
||||
_hj_k = keylen; \
|
||||
while (_hj_k >= 12) { \
|
||||
_hj_i += (_hj_key[0] + ( (unsigned)_hj_key[1] << 8 ) \
|
||||
+ ( (unsigned)_hj_key[2] << 16 ) \
|
||||
+ ( (unsigned)_hj_key[3] << 24 ) ); \
|
||||
_hj_j += (_hj_key[4] + ( (unsigned)_hj_key[5] << 8 ) \
|
||||
+ ( (unsigned)_hj_key[6] << 16 ) \
|
||||
+ ( (unsigned)_hj_key[7] << 24 ) ); \
|
||||
hashv += (_hj_key[8] + ( (unsigned)_hj_key[9] << 8 ) \
|
||||
+ ( (unsigned)_hj_key[10] << 16 ) \
|
||||
+ ( (unsigned)_hj_key[11] << 24 ) ); \
|
||||
\
|
||||
HASH_JEN_MIX(_hj_i, _hj_j, hashv); \
|
||||
\
|
||||
_hj_key += 12; \
|
||||
_hj_k -= 12; \
|
||||
} \
|
||||
hashv += keylen; \
|
||||
switch ( _hj_k ) { \
|
||||
case 11: hashv += ( (unsigned)_hj_key[10] << 24 ); \
|
||||
case 10: hashv += ( (unsigned)_hj_key[9] << 16 ); \
|
||||
case 9: hashv += ( (unsigned)_hj_key[8] << 8 ); \
|
||||
case 8: _hj_j += ( (unsigned)_hj_key[7] << 24 ); \
|
||||
case 7: _hj_j += ( (unsigned)_hj_key[6] << 16 ); \
|
||||
case 6: _hj_j += ( (unsigned)_hj_key[5] << 8 ); \
|
||||
case 5: _hj_j += _hj_key[4]; \
|
||||
case 4: _hj_i += ( (unsigned)_hj_key[3] << 24 ); \
|
||||
case 3: _hj_i += ( (unsigned)_hj_key[2] << 16 ); \
|
||||
case 2: _hj_i += ( (unsigned)_hj_key[1] << 8 ); \
|
||||
case 1: _hj_i += _hj_key[0]; \
|
||||
} \
|
||||
HASH_JEN_MIX(_hj_i, _hj_j, hashv); \
|
||||
bkt = hashv & (num_bkts-1); \
|
||||
} while(0)
|
||||
|
||||
/* The Paul Hsieh hash function */
|
||||
#undef get16bits
|
||||
#if (defined(__GNUC__) && defined(__i386__)) || defined(__WATCOMC__) \
|
||||
|| defined(_MSC_VER) || defined (__BORLANDC__) || defined (__TURBOC__)
|
||||
#define get16bits(d) (*((const uint16_t *) (d)))
|
||||
#endif
|
||||
|
||||
#if !defined (get16bits)
|
||||
#define get16bits(d) ((((uint32_t)(((const uint8_t *)(d))[1])) << 8) \
|
||||
+(uint32_t)(((const uint8_t *)(d))[0]) )
|
||||
#endif
|
||||
#define HASH_SFH(key,keylen,num_bkts,hashv,bkt) \
|
||||
do { \
|
||||
char *_sfh_key=(char*)key; \
|
||||
uint32_t _sfh_tmp, _sfh_len = keylen; \
|
||||
\
|
||||
int _sfh_rem = _sfh_len & 3; \
|
||||
_sfh_len >>= 2; \
|
||||
hashv = 0xcafebabe; \
|
||||
\
|
||||
/* Main loop */ \
|
||||
for (;_sfh_len > 0; _sfh_len--) { \
|
||||
hashv += get16bits (_sfh_key); \
|
||||
_sfh_tmp = (get16bits (_sfh_key+2) << 11) ^ hashv; \
|
||||
hashv = (hashv << 16) ^ _sfh_tmp; \
|
||||
_sfh_key += 2*sizeof (uint16_t); \
|
||||
hashv += hashv >> 11; \
|
||||
} \
|
||||
\
|
||||
/* Handle end cases */ \
|
||||
switch (_sfh_rem) { \
|
||||
case 3: hashv += get16bits (_sfh_key); \
|
||||
hashv ^= hashv << 16; \
|
||||
hashv ^= _sfh_key[sizeof (uint16_t)] << 18; \
|
||||
hashv += hashv >> 11; \
|
||||
break; \
|
||||
case 2: hashv += get16bits (_sfh_key); \
|
||||
hashv ^= hashv << 11; \
|
||||
hashv += hashv >> 17; \
|
||||
break; \
|
||||
case 1: hashv += *_sfh_key; \
|
||||
hashv ^= hashv << 10; \
|
||||
hashv += hashv >> 1; \
|
||||
} \
|
||||
\
|
||||
/* Force "avalanching" of final 127 bits */ \
|
||||
hashv ^= hashv << 3; \
|
||||
hashv += hashv >> 5; \
|
||||
hashv ^= hashv << 4; \
|
||||
hashv += hashv >> 17; \
|
||||
hashv ^= hashv << 25; \
|
||||
hashv += hashv >> 6; \
|
||||
bkt = hashv & (num_bkts-1); \
|
||||
} while(0);
|
||||
|
||||
#ifdef HASH_USING_NO_STRICT_ALIASING
|
||||
/* The MurmurHash exploits some CPU's (e.g. x86) tolerance for unaligned reads.
|
||||
* For other types of CPU's (e.g. Sparc) an unaligned read causes a bus error.
|
||||
* So MurmurHash comes in two versions, the faster unaligned one and the slower
|
||||
* aligned one. We only use the faster one on CPU's where we know it's safe.
|
||||
*
|
||||
* Note the preprocessor built-in defines can be emitted using:
|
||||
*
|
||||
* gcc -m64 -dM -E - < /dev/null (on gcc)
|
||||
* cc -## a.c (where a.c is a simple test file) (Sun Studio)
|
||||
*/
|
||||
#if (defined(__i386__) || defined(__x86_64__))
|
||||
#define HASH_MUR HASH_MUR_UNALIGNED
|
||||
#else
|
||||
#define HASH_MUR HASH_MUR_ALIGNED
|
||||
#endif
|
||||
|
||||
/* Appleby's MurmurHash fast version for unaligned-tolerant archs like i386 */
|
||||
#define HASH_MUR_UNALIGNED(key,keylen,num_bkts,hashv,bkt) \
|
||||
do { \
|
||||
const unsigned int _mur_m = 0x5bd1e995; \
|
||||
const int _mur_r = 24; \
|
||||
hashv = 0xcafebabe ^ keylen; \
|
||||
char *_mur_key = (char *)key; \
|
||||
uint32_t _mur_tmp, _mur_len = keylen; \
|
||||
\
|
||||
for (;_mur_len >= 4; _mur_len-=4) { \
|
||||
_mur_tmp = *(uint32_t *)_mur_key; \
|
||||
_mur_tmp *= _mur_m; \
|
||||
_mur_tmp ^= _mur_tmp >> _mur_r; \
|
||||
_mur_tmp *= _mur_m; \
|
||||
hashv *= _mur_m; \
|
||||
hashv ^= _mur_tmp; \
|
||||
_mur_key += 4; \
|
||||
} \
|
||||
\
|
||||
switch(_mur_len) \
|
||||
{ \
|
||||
case 3: hashv ^= _mur_key[2] << 16; \
|
||||
case 2: hashv ^= _mur_key[1] << 8; \
|
||||
case 1: hashv ^= _mur_key[0]; \
|
||||
hashv *= _mur_m; \
|
||||
}; \
|
||||
\
|
||||
hashv ^= hashv >> 13; \
|
||||
hashv *= _mur_m; \
|
||||
hashv ^= hashv >> 15; \
|
||||
\
|
||||
bkt = hashv & (num_bkts-1); \
|
||||
} while(0)
|
||||
|
||||
/* Appleby's MurmurHash version for alignment-sensitive archs like Sparc */
|
||||
#define HASH_MUR_ALIGNED(key,keylen,num_bkts,hashv,bkt) \
|
||||
do { \
|
||||
const unsigned int _mur_m = 0x5bd1e995; \
|
||||
const int _mur_r = 24; \
|
||||
hashv = 0xcafebabe ^ keylen; \
|
||||
char *_mur_key = (char *)key; \
|
||||
uint32_t _mur_len = keylen; \
|
||||
int _mur_align = (int)_mur_key & 3; \
|
||||
\
|
||||
if (_mur_align && (_mur_len >= 4)) { \
|
||||
unsigned _mur_t = 0, _mur_d = 0; \
|
||||
switch(_mur_align) { \
|
||||
case 1: _mur_t |= _mur_key[2] << 16; \
|
||||
case 2: _mur_t |= _mur_key[1] << 8; \
|
||||
case 3: _mur_t |= _mur_key[0]; \
|
||||
} \
|
||||
_mur_t <<= (8 * _mur_align); \
|
||||
_mur_key += 4-_mur_align; \
|
||||
_mur_len -= 4-_mur_align; \
|
||||
int _mur_sl = 8 * (4-_mur_align); \
|
||||
int _mur_sr = 8 * _mur_align; \
|
||||
\
|
||||
for (;_mur_len >= 4; _mur_len-=4) { \
|
||||
_mur_d = *(unsigned *)_mur_key; \
|
||||
_mur_t = (_mur_t >> _mur_sr) | (_mur_d << _mur_sl); \
|
||||
unsigned _mur_k = _mur_t; \
|
||||
_mur_k *= _mur_m; \
|
||||
_mur_k ^= _mur_k >> _mur_r; \
|
||||
_mur_k *= _mur_m; \
|
||||
hashv *= _mur_m; \
|
||||
hashv ^= _mur_k; \
|
||||
_mur_t = _mur_d; \
|
||||
_mur_key += 4; \
|
||||
} \
|
||||
_mur_d = 0; \
|
||||
if(_mur_len >= _mur_align) { \
|
||||
switch(_mur_align) { \
|
||||
case 3: _mur_d |= _mur_key[2] << 16; \
|
||||
case 2: _mur_d |= _mur_key[1] << 8; \
|
||||
case 1: _mur_d |= _mur_key[0]; \
|
||||
} \
|
||||
unsigned _mur_k = (_mur_t >> _mur_sr) | (_mur_d << _mur_sl); \
|
||||
_mur_k *= _mur_m; \
|
||||
_mur_k ^= _mur_k >> _mur_r; \
|
||||
_mur_k *= _mur_m; \
|
||||
hashv *= _mur_m; \
|
||||
hashv ^= _mur_k; \
|
||||
_mur_k += _mur_align; \
|
||||
_mur_len -= _mur_align; \
|
||||
\
|
||||
switch(_mur_len) \
|
||||
{ \
|
||||
case 3: hashv ^= _mur_key[2] << 16; \
|
||||
case 2: hashv ^= _mur_key[1] << 8; \
|
||||
case 1: hashv ^= _mur_key[0]; \
|
||||
hashv *= _mur_m; \
|
||||
} \
|
||||
} else { \
|
||||
switch(_mur_len) \
|
||||
{ \
|
||||
case 3: _mur_d ^= _mur_key[2] << 16; \
|
||||
case 2: _mur_d ^= _mur_key[1] << 8; \
|
||||
case 1: _mur_d ^= _mur_key[0]; \
|
||||
case 0: hashv ^= (_mur_t >> _mur_sr) | (_mur_d << _mur_sl); \
|
||||
hashv *= _mur_m; \
|
||||
} \
|
||||
} \
|
||||
\
|
||||
hashv ^= hashv >> 13; \
|
||||
hashv *= _mur_m; \
|
||||
hashv ^= hashv >> 15; \
|
||||
} else { \
|
||||
for (;_mur_len >= 4; _mur_len-=4) { \
|
||||
unsigned _mur_k = *(unsigned*)_mur_key; \
|
||||
_mur_k *= _mur_m; \
|
||||
_mur_k ^= _mur_k >> _mur_r; \
|
||||
_mur_k *= _mur_m; \
|
||||
hashv *= _mur_m; \
|
||||
hashv ^= _mur_k; \
|
||||
_mur_key += 4; \
|
||||
} \
|
||||
switch(_mur_len) \
|
||||
{ \
|
||||
case 3: hashv ^= _mur_key[2] << 16; \
|
||||
case 2: hashv ^= _mur_key[1] << 8; \
|
||||
case 1: hashv ^= _mur_key[0]; \
|
||||
hashv *= _mur_m; \
|
||||
} \
|
||||
\
|
||||
hashv ^= hashv >> 13; \
|
||||
hashv *= _mur_m; \
|
||||
hashv ^= hashv >> 15; \
|
||||
} \
|
||||
bkt = hashv & (num_bkts-1); \
|
||||
} while(0)
|
||||
#endif /* HASH_USING_NO_STRICT_ALIASING */
|
||||
|
||||
/* key comparison function; return 0 if keys equal */
|
||||
#define HASH_KEYCMP(a,b,len) memcmp(a,b,len)
|
||||
|
||||
/* iterate over items in a known bucket to find desired item */
|
||||
#define HASH_FIND_IN_BKT(tbl,hh,head,keyptr,keylen_in,out) \
|
||||
do { \
|
||||
if (head.hh_head) DECLTYPE_ASSIGN(out,ELMT_FROM_HH(tbl,head.hh_head)); \
|
||||
else out=NULL; \
|
||||
while (out) { \
|
||||
if (out->hh.keylen == keylen_in) { \
|
||||
if ((HASH_KEYCMP(out->hh.key,keyptr,keylen_in)) == 0) break; \
|
||||
} \
|
||||
if (out->hh.hh_next) DECLTYPE_ASSIGN(out,ELMT_FROM_HH(tbl,out->hh.hh_next)); \
|
||||
else out = NULL; \
|
||||
} \
|
||||
} while(0)
|
||||
|
||||
/* add an item to a bucket */
|
||||
#define HASH_ADD_TO_BKT(head,addhh) \
|
||||
do { \
|
||||
head.count++; \
|
||||
(addhh)->hh_next = head.hh_head; \
|
||||
(addhh)->hh_prev = NULL; \
|
||||
if (head.hh_head) { (head).hh_head->hh_prev = (addhh); } \
|
||||
(head).hh_head=addhh; \
|
||||
if (head.count >= ((head.expand_mult+1) * HASH_BKT_CAPACITY_THRESH) \
|
||||
&& (addhh)->tbl->noexpand != 1) { \
|
||||
HASH_EXPAND_BUCKETS((addhh)->tbl); \
|
||||
} \
|
||||
} while(0)
|
||||
|
||||
/* remove an item from a given bucket */
|
||||
#define HASH_DEL_IN_BKT(hh,head,hh_del) \
|
||||
(head).count--; \
|
||||
if ((head).hh_head == hh_del) { \
|
||||
(head).hh_head = hh_del->hh_next; \
|
||||
} \
|
||||
if (hh_del->hh_prev) { \
|
||||
hh_del->hh_prev->hh_next = hh_del->hh_next; \
|
||||
} \
|
||||
if (hh_del->hh_next) { \
|
||||
hh_del->hh_next->hh_prev = hh_del->hh_prev; \
|
||||
}
|
||||
|
||||
/* Bucket expansion has the effect of doubling the number of buckets
|
||||
* and redistributing the items into the new buckets. Ideally the
|
||||
* items will distribute more or less evenly into the new buckets
|
||||
* (the extent to which this is true is a measure of the quality of
|
||||
* the hash function as it applies to the key domain).
|
||||
*
|
||||
* With the items distributed into more buckets, the chain length
|
||||
* (item count) in each bucket is reduced. Thus by expanding buckets
|
||||
* the hash keeps a bound on the chain length. This bounded chain
|
||||
* length is the essence of how a hash provides constant time lookup.
|
||||
*
|
||||
* The calculation of tbl->ideal_chain_maxlen below deserves some
|
||||
* explanation. First, keep in mind that we're calculating the ideal
|
||||
* maximum chain length based on the *new* (doubled) bucket count.
|
||||
* In fractions this is just n/b (n=number of items,b=new num buckets).
|
||||
* Since the ideal chain length is an integer, we want to calculate
|
||||
* ceil(n/b). We don't depend on floating point arithmetic in this
|
||||
* hash, so to calculate ceil(n/b) with integers we could write
|
||||
*
|
||||
* ceil(n/b) = (n/b) + ((n%b)?1:0)
|
||||
*
|
||||
* and in fact a previous version of this hash did just that.
|
||||
* But now we have improved things a bit by recognizing that b is
|
||||
* always a power of two. We keep its base 2 log handy (call it lb),
|
||||
* so now we can write this with a bit shift and logical AND:
|
||||
*
|
||||
* ceil(n/b) = (n>>lb) + ( (n & (b-1)) ? 1:0)
|
||||
*
|
||||
*/
|
||||
#define HASH_EXPAND_BUCKETS(tbl) \
|
||||
do { \
|
||||
unsigned _he_bkt; \
|
||||
unsigned _he_bkt_i; \
|
||||
struct UT_hash_handle *_he_thh, *_he_hh_nxt; \
|
||||
UT_hash_bucket *_he_new_buckets, *_he_newbkt; \
|
||||
_he_new_buckets = (UT_hash_bucket*)uthash_malloc( \
|
||||
2 * tbl->num_buckets * sizeof(struct UT_hash_bucket)); \
|
||||
if (!_he_new_buckets) { uthash_fatal( "out of memory"); } \
|
||||
memset(_he_new_buckets, 0, \
|
||||
2 * tbl->num_buckets * sizeof(struct UT_hash_bucket)); \
|
||||
tbl->ideal_chain_maxlen = \
|
||||
(tbl->num_items >> (tbl->log2_num_buckets+1)) + \
|
||||
((tbl->num_items & ((tbl->num_buckets*2)-1)) ? 1 : 0); \
|
||||
tbl->nonideal_items = 0; \
|
||||
for(_he_bkt_i = 0; _he_bkt_i < tbl->num_buckets; _he_bkt_i++) \
|
||||
{ \
|
||||
_he_thh = tbl->buckets[ _he_bkt_i ].hh_head; \
|
||||
while (_he_thh) { \
|
||||
_he_hh_nxt = _he_thh->hh_next; \
|
||||
HASH_TO_BKT( _he_thh->hashv, tbl->num_buckets*2, _he_bkt); \
|
||||
_he_newbkt = &(_he_new_buckets[ _he_bkt ]); \
|
||||
if (++(_he_newbkt->count) > tbl->ideal_chain_maxlen) { \
|
||||
tbl->nonideal_items++; \
|
||||
_he_newbkt->expand_mult = _he_newbkt->count / \
|
||||
tbl->ideal_chain_maxlen; \
|
||||
} \
|
||||
_he_thh->hh_prev = NULL; \
|
||||
_he_thh->hh_next = _he_newbkt->hh_head; \
|
||||
if (_he_newbkt->hh_head) _he_newbkt->hh_head->hh_prev = \
|
||||
_he_thh; \
|
||||
_he_newbkt->hh_head = _he_thh; \
|
||||
_he_thh = _he_hh_nxt; \
|
||||
} \
|
||||
} \
|
||||
tbl->num_buckets *= 2; \
|
||||
tbl->log2_num_buckets++; \
|
||||
uthash_free( tbl->buckets ); \
|
||||
tbl->buckets = _he_new_buckets; \
|
||||
tbl->ineff_expands = (tbl->nonideal_items > (tbl->num_items >> 1)) ? \
|
||||
(tbl->ineff_expands+1) : 0; \
|
||||
if (tbl->ineff_expands > 1) { \
|
||||
tbl->noexpand=1; \
|
||||
uthash_noexpand_fyi(tbl); \
|
||||
} \
|
||||
uthash_expand_fyi(tbl); \
|
||||
} while(0)
|
||||
|
||||
|
||||
/* This is an adaptation of Simon Tatham's O(n log(n)) mergesort */
|
||||
/* Note that HASH_SORT assumes the hash handle name to be hh.
|
||||
* HASH_SRT was added to allow the hash handle name to be passed in. */
|
||||
#define HASH_SORT(head,cmpfcn) HASH_SRT(hh,head,cmpfcn)
|
||||
#define HASH_SRT(hh,head,cmpfcn) \
|
||||
do { \
|
||||
unsigned _hs_i; \
|
||||
unsigned _hs_looping,_hs_nmerges,_hs_insize,_hs_psize,_hs_qsize; \
|
||||
struct UT_hash_handle *_hs_p, *_hs_q, *_hs_e, *_hs_list, *_hs_tail; \
|
||||
if (head) { \
|
||||
_hs_insize = 1; \
|
||||
_hs_looping = 1; \
|
||||
_hs_list = &((head)->hh); \
|
||||
while (_hs_looping) { \
|
||||
_hs_p = _hs_list; \
|
||||
_hs_list = NULL; \
|
||||
_hs_tail = NULL; \
|
||||
_hs_nmerges = 0; \
|
||||
while (_hs_p) { \
|
||||
_hs_nmerges++; \
|
||||
_hs_q = _hs_p; \
|
||||
_hs_psize = 0; \
|
||||
for ( _hs_i = 0; _hs_i < _hs_insize; _hs_i++ ) { \
|
||||
_hs_psize++; \
|
||||
_hs_q = (UT_hash_handle*)((_hs_q->next) ? \
|
||||
((void*)((char*)(_hs_q->next) + \
|
||||
(head)->hh.tbl->hho)) : NULL); \
|
||||
if (! (_hs_q) ) break; \
|
||||
} \
|
||||
_hs_qsize = _hs_insize; \
|
||||
while ((_hs_psize > 0) || ((_hs_qsize > 0) && _hs_q )) { \
|
||||
if (_hs_psize == 0) { \
|
||||
_hs_e = _hs_q; \
|
||||
_hs_q = (UT_hash_handle*)((_hs_q->next) ? \
|
||||
((void*)((char*)(_hs_q->next) + \
|
||||
(head)->hh.tbl->hho)) : NULL); \
|
||||
_hs_qsize--; \
|
||||
} else if ( (_hs_qsize == 0) || !(_hs_q) ) { \
|
||||
_hs_e = _hs_p; \
|
||||
_hs_p = (UT_hash_handle*)((_hs_p->next) ? \
|
||||
((void*)((char*)(_hs_p->next) + \
|
||||
(head)->hh.tbl->hho)) : NULL); \
|
||||
_hs_psize--; \
|
||||
} else if (( \
|
||||
cmpfcn(DECLTYPE(head)(ELMT_FROM_HH((head)->hh.tbl,_hs_p)), \
|
||||
DECLTYPE(head)(ELMT_FROM_HH((head)->hh.tbl,_hs_q))) \
|
||||
) <= 0) { \
|
||||
_hs_e = _hs_p; \
|
||||
_hs_p = (UT_hash_handle*)((_hs_p->next) ? \
|
||||
((void*)((char*)(_hs_p->next) + \
|
||||
(head)->hh.tbl->hho)) : NULL); \
|
||||
_hs_psize--; \
|
||||
} else { \
|
||||
_hs_e = _hs_q; \
|
||||
_hs_q = (UT_hash_handle*)((_hs_q->next) ? \
|
||||
((void*)((char*)(_hs_q->next) + \
|
||||
(head)->hh.tbl->hho)) : NULL); \
|
||||
_hs_qsize--; \
|
||||
} \
|
||||
if ( _hs_tail ) { \
|
||||
_hs_tail->next = ((_hs_e) ? \
|
||||
ELMT_FROM_HH((head)->hh.tbl,_hs_e) : NULL); \
|
||||
} else { \
|
||||
_hs_list = _hs_e; \
|
||||
} \
|
||||
_hs_e->prev = ((_hs_tail) ? \
|
||||
ELMT_FROM_HH((head)->hh.tbl,_hs_tail) : NULL); \
|
||||
_hs_tail = _hs_e; \
|
||||
} \
|
||||
_hs_p = _hs_q; \
|
||||
} \
|
||||
_hs_tail->next = NULL; \
|
||||
if ( _hs_nmerges <= 1 ) { \
|
||||
_hs_looping=0; \
|
||||
(head)->hh.tbl->tail = _hs_tail; \
|
||||
DECLTYPE_ASSIGN(head,ELMT_FROM_HH((head)->hh.tbl, _hs_list)); \
|
||||
} \
|
||||
_hs_insize *= 2; \
|
||||
} \
|
||||
HASH_FSCK(hh,head); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
/* This function selects items from one hash into another hash.
|
||||
* The end result is that the selected items have dual presence
|
||||
* in both hashes. There is no copy of the items made; rather
|
||||
* they are added into the new hash through a secondary hash
|
||||
* hash handle that must be present in the structure. */
|
||||
#define HASH_SELECT(hh_dst, dst, hh_src, src, cond) \
|
||||
do { \
|
||||
unsigned _src_bkt, _dst_bkt; \
|
||||
void *_last_elt=NULL, *_elt; \
|
||||
UT_hash_handle *_src_hh, *_dst_hh, *_last_elt_hh=NULL; \
|
||||
ptrdiff_t _dst_hho = ((char*)(&(dst)->hh_dst) - (char*)(dst)); \
|
||||
if (src) { \
|
||||
for(_src_bkt=0; _src_bkt < (src)->hh_src.tbl->num_buckets; _src_bkt++) { \
|
||||
for(_src_hh = (src)->hh_src.tbl->buckets[_src_bkt].hh_head; \
|
||||
_src_hh; \
|
||||
_src_hh = _src_hh->hh_next) { \
|
||||
_elt = ELMT_FROM_HH((src)->hh_src.tbl, _src_hh); \
|
||||
if (cond(_elt)) { \
|
||||
_dst_hh = (UT_hash_handle*)(((char*)_elt) + _dst_hho); \
|
||||
_dst_hh->key = _src_hh->key; \
|
||||
_dst_hh->keylen = _src_hh->keylen; \
|
||||
_dst_hh->hashv = _src_hh->hashv; \
|
||||
_dst_hh->prev = _last_elt; \
|
||||
_dst_hh->next = NULL; \
|
||||
if (_last_elt_hh) { _last_elt_hh->next = _elt; } \
|
||||
if (!dst) { \
|
||||
DECLTYPE_ASSIGN(dst,_elt); \
|
||||
HASH_MAKE_TABLE(hh_dst,dst); \
|
||||
} else { \
|
||||
_dst_hh->tbl = (dst)->hh_dst.tbl; \
|
||||
} \
|
||||
HASH_TO_BKT(_dst_hh->hashv, _dst_hh->tbl->num_buckets, _dst_bkt); \
|
||||
HASH_ADD_TO_BKT(_dst_hh->tbl->buckets[_dst_bkt],_dst_hh); \
|
||||
(dst)->hh_dst.tbl->num_items++; \
|
||||
_last_elt = _elt; \
|
||||
_last_elt_hh = _dst_hh; \
|
||||
} \
|
||||
} \
|
||||
} \
|
||||
} \
|
||||
HASH_FSCK(hh_dst,dst); \
|
||||
} while (0)
|
||||
|
||||
#define HASH_CLEAR(hh,head) \
|
||||
do { \
|
||||
if (head) { \
|
||||
uthash_free((head)->hh.tbl->buckets ); \
|
||||
uthash_free((head)->hh.tbl); \
|
||||
(head)=NULL; \
|
||||
} \
|
||||
} while(0)
|
||||
|
||||
/* obtain a count of items in the hash */
|
||||
#define HASH_COUNT(head) HASH_CNT(hh,head)
|
||||
#define HASH_CNT(hh,head) (head?(head->hh.tbl->num_items):0)
|
||||
|
||||
typedef struct UT_hash_bucket {
|
||||
struct UT_hash_handle *hh_head;
|
||||
unsigned count;
|
||||
|
||||
/* expand_mult is normally set to 0. In this situation, the max chain length
|
||||
* threshold is enforced at its default value, HASH_BKT_CAPACITY_THRESH. (If
|
||||
* the bucket's chain exceeds this length, bucket expansion is triggered).
|
||||
* However, setting expand_mult to a non-zero value delays bucket expansion
|
||||
* (that would be triggered by additions to this particular bucket)
|
||||
* until its chain length reaches a *multiple* of HASH_BKT_CAPACITY_THRESH.
|
||||
* (The multiplier is simply expand_mult+1). The whole idea of this
|
||||
* multiplier is to reduce bucket expansions, since they are expensive, in
|
||||
* situations where we know that a particular bucket tends to be overused.
|
||||
* It is better to let its chain length grow to a longer yet-still-bounded
|
||||
* value, than to do an O(n) bucket expansion too often.
|
||||
*/
|
||||
unsigned expand_mult;
|
||||
|
||||
} UT_hash_bucket;
|
||||
|
||||
/* random signature used only to find hash tables in external analysis */
|
||||
#define HASH_SIGNATURE 0xa0111fe1
|
||||
#define HASH_BLOOM_SIGNATURE 0xb12220f2
|
||||
|
||||
typedef struct UT_hash_table {
|
||||
UT_hash_bucket *buckets;
|
||||
unsigned num_buckets, log2_num_buckets;
|
||||
unsigned num_items;
|
||||
struct UT_hash_handle *tail; /* tail hh in app order, for fast append */
|
||||
ptrdiff_t hho; /* hash handle offset (byte pos of hash handle in element */
|
||||
|
||||
/* in an ideal situation (all buckets used equally), no bucket would have
|
||||
* more than ceil(#items/#buckets) items. that's the ideal chain length. */
|
||||
unsigned ideal_chain_maxlen;
|
||||
|
||||
/* nonideal_items is the number of items in the hash whose chain position
|
||||
* exceeds the ideal chain maxlen. these items pay the penalty for an uneven
|
||||
* hash distribution; reaching them in a chain traversal takes >ideal steps */
|
||||
unsigned nonideal_items;
|
||||
|
||||
/* ineffective expands occur when a bucket doubling was performed, but
|
||||
* afterward, more than half the items in the hash had nonideal chain
|
||||
* positions. If this happens on two consecutive expansions we inhibit any
|
||||
* further expansion, as it's not helping; this happens when the hash
|
||||
* function isn't a good fit for the key domain. When expansion is inhibited
|
||||
* the hash will still work, albeit no longer in constant time. */
|
||||
unsigned ineff_expands, noexpand;
|
||||
|
||||
uint32_t signature; /* used only to find hash tables in external analysis */
|
||||
#ifdef HASH_BLOOM
|
||||
uint32_t bloom_sig; /* used only to test bloom exists in external analysis */
|
||||
uint8_t *bloom_bv;
|
||||
char bloom_nbits;
|
||||
#endif
|
||||
|
||||
} UT_hash_table;
|
||||
|
||||
typedef struct UT_hash_handle {
|
||||
struct UT_hash_table *tbl;
|
||||
void *prev; /* prev element in app order */
|
||||
void *next; /* next element in app order */
|
||||
struct UT_hash_handle *hh_prev; /* previous hh in bucket order */
|
||||
struct UT_hash_handle *hh_next; /* next hh in bucket order */
|
||||
void *key; /* ptr to enclosing struct's key */
|
||||
unsigned keylen; /* enclosing struct's key len */
|
||||
unsigned hashv; /* result of hash-fcn(key) */
|
||||
} UT_hash_handle;
|
||||
|
||||
#endif /* UTHASH_H */
|
1392
thirdparty/libktx/lib/vk_format.h
vendored
Normal file
1392
thirdparty/libktx/lib/vk_format.h
vendored
Normal file
File diff suppressed because it is too large
Load Diff
215
thirdparty/libktx/lib/vkformat_check.c
vendored
Normal file
215
thirdparty/libktx/lib/vkformat_check.c
vendored
Normal file
@@ -0,0 +1,215 @@
|
||||
|
||||
/***************************** Do not edit. *****************************
|
||||
Automatically generated from vulkan_core.h version 287 by mkvkformatfiles.
|
||||
*************************************************************************/
|
||||
|
||||
/*
|
||||
** Copyright 2015-2024 The Khronos Group Inc.
|
||||
**
|
||||
** SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
// clang-format off: CI is complicated if formatting checks on generated files are enforced.
|
||||
#include <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_USCALED_PACK32:
|
||||
case VK_FORMAT_A8B8G8R8_SSCALED_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
|
||||
isSrgbFormat(VkFormat format)
|
||||
{
|
||||
switch(format) {
|
||||
case VK_FORMAT_R8_SRGB:
|
||||
case VK_FORMAT_R8G8_SRGB:
|
||||
case VK_FORMAT_R8G8B8_SRGB:
|
||||
case VK_FORMAT_B8G8R8_SRGB:
|
||||
case VK_FORMAT_R8G8B8A8_SRGB:
|
||||
case VK_FORMAT_B8G8R8A8_SRGB:
|
||||
case VK_FORMAT_A8B8G8R8_SRGB_PACK32:
|
||||
case VK_FORMAT_BC1_RGB_SRGB_BLOCK:
|
||||
case VK_FORMAT_BC1_RGBA_SRGB_BLOCK:
|
||||
case VK_FORMAT_BC2_SRGB_BLOCK:
|
||||
case VK_FORMAT_BC3_SRGB_BLOCK:
|
||||
case VK_FORMAT_BC7_SRGB_BLOCK:
|
||||
case VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK:
|
||||
case VK_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK:
|
||||
case VK_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK:
|
||||
case VK_FORMAT_ASTC_4x4_SRGB_BLOCK:
|
||||
case VK_FORMAT_ASTC_5x4_SRGB_BLOCK:
|
||||
case VK_FORMAT_ASTC_5x5_SRGB_BLOCK:
|
||||
case VK_FORMAT_ASTC_6x5_SRGB_BLOCK:
|
||||
case VK_FORMAT_ASTC_6x6_SRGB_BLOCK:
|
||||
case VK_FORMAT_ASTC_8x5_SRGB_BLOCK:
|
||||
case VK_FORMAT_ASTC_8x6_SRGB_BLOCK:
|
||||
case VK_FORMAT_ASTC_8x8_SRGB_BLOCK:
|
||||
case VK_FORMAT_ASTC_10x5_SRGB_BLOCK:
|
||||
case VK_FORMAT_ASTC_10x6_SRGB_BLOCK:
|
||||
case VK_FORMAT_ASTC_10x8_SRGB_BLOCK:
|
||||
case VK_FORMAT_ASTC_10x10_SRGB_BLOCK:
|
||||
case VK_FORMAT_ASTC_12x10_SRGB_BLOCK:
|
||||
case VK_FORMAT_ASTC_12x12_SRGB_BLOCK:
|
||||
case VK_FORMAT_PVRTC1_2BPP_SRGB_BLOCK_IMG:
|
||||
case VK_FORMAT_PVRTC1_4BPP_SRGB_BLOCK_IMG:
|
||||
case VK_FORMAT_PVRTC2_2BPP_SRGB_BLOCK_IMG:
|
||||
case VK_FORMAT_PVRTC2_4BPP_SRGB_BLOCK_IMG:
|
||||
case VK_FORMAT_ASTC_3x3x3_SRGB_BLOCK_EXT:
|
||||
case VK_FORMAT_ASTC_4x3x3_SRGB_BLOCK_EXT:
|
||||
case VK_FORMAT_ASTC_4x4x3_SRGB_BLOCK_EXT:
|
||||
case VK_FORMAT_ASTC_4x4x4_SRGB_BLOCK_EXT:
|
||||
case VK_FORMAT_ASTC_5x4x4_SRGB_BLOCK_EXT:
|
||||
case VK_FORMAT_ASTC_5x5x4_SRGB_BLOCK_EXT:
|
||||
case VK_FORMAT_ASTC_5x5x5_SRGB_BLOCK_EXT:
|
||||
case VK_FORMAT_ASTC_6x5x5_SRGB_BLOCK_EXT:
|
||||
case VK_FORMAT_ASTC_6x6x5_SRGB_BLOCK_EXT:
|
||||
case VK_FORMAT_ASTC_6x6x6_SRGB_BLOCK_EXT:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
isValidFormat(VkFormat format)
|
||||
{
|
||||
// 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_SFIXED5_NV:
|
||||
case VK_FORMAT_A1B5G5R5_UNORM_PACK16_KHR:
|
||||
case VK_FORMAT_A8_UNORM_KHR:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// clang-format on
|
171
thirdparty/libktx/lib/vkformat_check_variant.c
vendored
Normal file
171
thirdparty/libktx/lib/vkformat_check_variant.c
vendored
Normal file
@@ -0,0 +1,171 @@
|
||||
/*
|
||||
** Copyright 2025 The Khronos Group Inc.
|
||||
**
|
||||
** SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#include "vkformat_enum.h"
|
||||
|
||||
bool
|
||||
isNotSrgbFormatButHasSrgbVariant(VkFormat format)
|
||||
{
|
||||
switch (format) {
|
||||
// VK_FORMAT_R8_SRGB
|
||||
case VK_FORMAT_R8_UNORM:
|
||||
case VK_FORMAT_R8_SNORM:
|
||||
case VK_FORMAT_R8_UINT:
|
||||
case VK_FORMAT_R8_SINT:
|
||||
|
||||
// VK_FORMAT_R8G8_SRGB
|
||||
case VK_FORMAT_R8G8_UNORM:
|
||||
case VK_FORMAT_R8G8_SNORM:
|
||||
case VK_FORMAT_R8G8_UINT:
|
||||
case VK_FORMAT_R8G8_SINT:
|
||||
|
||||
// VK_FORMAT_R8G8B8_SRGB
|
||||
case VK_FORMAT_R8G8B8_UNORM:
|
||||
case VK_FORMAT_R8G8B8_SNORM:
|
||||
case VK_FORMAT_R8G8B8_UINT:
|
||||
case VK_FORMAT_R8G8B8_SINT:
|
||||
|
||||
// VK_FORMAT_B8G8R8_SRGB
|
||||
case VK_FORMAT_B8G8R8_UNORM:
|
||||
case VK_FORMAT_B8G8R8_SNORM:
|
||||
case VK_FORMAT_B8G8R8_UINT:
|
||||
case VK_FORMAT_B8G8R8_SINT:
|
||||
|
||||
// VK_FORMAT_R8G8B8A8_SRGB
|
||||
case VK_FORMAT_R8G8B8A8_UNORM:
|
||||
case VK_FORMAT_R8G8B8A8_SNORM:
|
||||
case VK_FORMAT_R8G8B8A8_UINT:
|
||||
case VK_FORMAT_R8G8B8A8_SINT:
|
||||
|
||||
// VK_FORMAT_B8G8R8A8_SRGB
|
||||
case VK_FORMAT_B8G8R8A8_UNORM:
|
||||
case VK_FORMAT_B8G8R8A8_SNORM:
|
||||
case VK_FORMAT_B8G8R8A8_UINT:
|
||||
case VK_FORMAT_B8G8R8A8_SINT:
|
||||
|
||||
// VK_FORMAT_A8B8G8R8_SRGB_PACK32
|
||||
case VK_FORMAT_A8B8G8R8_UNORM_PACK32:
|
||||
case VK_FORMAT_A8B8G8R8_SNORM_PACK32:
|
||||
case VK_FORMAT_A8B8G8R8_UINT_PACK32:
|
||||
case VK_FORMAT_A8B8G8R8_SINT_PACK32:
|
||||
|
||||
// VK_FORMAT_BC1_RGB_SRGB_BLOCK
|
||||
case VK_FORMAT_BC1_RGB_UNORM_BLOCK:
|
||||
|
||||
// VK_FORMAT_BC1_RGBA_SRGB_BLOCK
|
||||
case VK_FORMAT_BC1_RGBA_UNORM_BLOCK:
|
||||
|
||||
// VK_FORMAT_BC2_SRGB_BLOCK
|
||||
case VK_FORMAT_BC2_UNORM_BLOCK:
|
||||
|
||||
// VK_FORMAT_BC3_SRGB_BLOCK
|
||||
case VK_FORMAT_BC3_UNORM_BLOCK:
|
||||
|
||||
// VK_FORMAT_BC7_SRGB_BLOCK
|
||||
case VK_FORMAT_BC7_UNORM_BLOCK:
|
||||
|
||||
// VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK
|
||||
case VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK:
|
||||
|
||||
// VK_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK
|
||||
case VK_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK:
|
||||
|
||||
// VK_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK
|
||||
case VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK:
|
||||
|
||||
// VK_FORMAT_ASTC_4x4_SRGB_BLOCK
|
||||
case VK_FORMAT_ASTC_4x4_UNORM_BLOCK:
|
||||
|
||||
// VK_FORMAT_ASTC_5x4_SRGB_BLOCK
|
||||
case VK_FORMAT_ASTC_5x4_UNORM_BLOCK:
|
||||
|
||||
// VK_FORMAT_ASTC_5x5_SRGB_BLOCK
|
||||
case VK_FORMAT_ASTC_5x5_UNORM_BLOCK:
|
||||
|
||||
// VK_FORMAT_ASTC_6x5_SRGB_BLOCK
|
||||
case VK_FORMAT_ASTC_6x5_UNORM_BLOCK:
|
||||
|
||||
// VK_FORMAT_ASTC_6x6_SRGB_BLOCK
|
||||
case VK_FORMAT_ASTC_6x6_UNORM_BLOCK:
|
||||
|
||||
// VK_FORMAT_ASTC_8x5_SRGB_BLOCK
|
||||
case VK_FORMAT_ASTC_8x5_UNORM_BLOCK:
|
||||
|
||||
// VK_FORMAT_ASTC_8x6_SRGB_BLOCK
|
||||
case VK_FORMAT_ASTC_8x6_UNORM_BLOCK:
|
||||
|
||||
// VK_FORMAT_ASTC_8x8_SRGB_BLOCK
|
||||
case VK_FORMAT_ASTC_8x8_UNORM_BLOCK:
|
||||
|
||||
// VK_FORMAT_ASTC_10x5_SRGB_BLOCK
|
||||
case VK_FORMAT_ASTC_10x5_UNORM_BLOCK:
|
||||
|
||||
// VK_FORMAT_ASTC_10x6_SRGB_BLOCK
|
||||
case VK_FORMAT_ASTC_10x6_UNORM_BLOCK:
|
||||
|
||||
// VK_FORMAT_ASTC_10x8_SRGB_BLOCK
|
||||
case VK_FORMAT_ASTC_10x8_UNORM_BLOCK:
|
||||
|
||||
// VK_FORMAT_ASTC_10x10_SRGB_BLOCK
|
||||
case VK_FORMAT_ASTC_10x10_UNORM_BLOCK:
|
||||
|
||||
// VK_FORMAT_ASTC_12x10_SRGB_BLOCK
|
||||
case VK_FORMAT_ASTC_12x10_UNORM_BLOCK:
|
||||
|
||||
// VK_FORMAT_ASTC_12x12_SRGB_BLOCK
|
||||
case VK_FORMAT_ASTC_12x12_UNORM_BLOCK:
|
||||
|
||||
// VK_FORMAT_PVRTC1_2BPP_SRGB_BLOCK_IMG
|
||||
case VK_FORMAT_PVRTC1_2BPP_UNORM_BLOCK_IMG:
|
||||
|
||||
// VK_FORMAT_PVRTC1_4BPP_SRGB_BLOCK_IMG
|
||||
case VK_FORMAT_PVRTC1_4BPP_UNORM_BLOCK_IMG:
|
||||
|
||||
// VK_FORMAT_PVRTC2_2BPP_SRGB_BLOCK_IMG
|
||||
case VK_FORMAT_PVRTC2_2BPP_UNORM_BLOCK_IMG:
|
||||
|
||||
// VK_FORMAT_PVRTC2_4BPP_SRGB_BLOCK_IMG
|
||||
case VK_FORMAT_PVRTC2_4BPP_UNORM_BLOCK_IMG:
|
||||
|
||||
// VK_FORMAT_ASTC_3x3x3_SRGB_BLOCK_EXT
|
||||
case VK_FORMAT_ASTC_3x3x3_UNORM_BLOCK_EXT:
|
||||
|
||||
// VK_FORMAT_ASTC_4x3x3_SRGB_BLOCK_EXT
|
||||
case VK_FORMAT_ASTC_4x3x3_UNORM_BLOCK_EXT:
|
||||
|
||||
// VK_FORMAT_ASTC_4x4x3_SRGB_BLOCK_EXT
|
||||
case VK_FORMAT_ASTC_4x4x3_UNORM_BLOCK_EXT:
|
||||
|
||||
// VK_FORMAT_ASTC_4x4x4_SRGB_BLOCK_EXT
|
||||
case VK_FORMAT_ASTC_4x4x4_UNORM_BLOCK_EXT:
|
||||
|
||||
// VK_FORMAT_ASTC_5x4x4_SRGB_BLOCK_EXT
|
||||
case VK_FORMAT_ASTC_5x4x4_UNORM_BLOCK_EXT:
|
||||
|
||||
// VK_FORMAT_ASTC_5x5x4_SRGB_BLOCK_EXT
|
||||
case VK_FORMAT_ASTC_5x5x4_UNORM_BLOCK_EXT:
|
||||
|
||||
// VK_FORMAT_ASTC_5x5x5_SRGB_BLOCK_EXT
|
||||
case VK_FORMAT_ASTC_5x5x5_UNORM_BLOCK_EXT:
|
||||
|
||||
// VK_FORMAT_ASTC_6x5x5_SRGB_BLOCK_EXT
|
||||
case VK_FORMAT_ASTC_6x5x5_UNORM_BLOCK_EXT:
|
||||
|
||||
// VK_FORMAT_ASTC_6x6x5_SRGB_BLOCK_EXT
|
||||
case VK_FORMAT_ASTC_6x6x5_UNORM_BLOCK_EXT:
|
||||
|
||||
// VK_FORMAT_ASTC_6x6x6_SRGB_BLOCK_EXT
|
||||
case VK_FORMAT_ASTC_6x6x6_UNORM_BLOCK_EXT:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
316
thirdparty/libktx/lib/vkformat_enum.h
vendored
Normal file
316
thirdparty/libktx/lib/vkformat_enum.h
vendored
Normal file
@@ -0,0 +1,316 @@
|
||||
// clang-format off: CI is complicated if formatting checks on generated files are enforced.
|
||||
#if !defined(_VKFORMAT_ENUM_H_) && !defined(VULKAN_CORE_H_)
|
||||
#define _VKFORMAT_ENUM_H_
|
||||
|
||||
/***************************** Do not edit. *****************************
|
||||
Automatically generated from vulkan_core.h version 287 by mkvkformatfiles.
|
||||
*************************************************************************/
|
||||
|
||||
/*
|
||||
** Copyright 2015-2024 The Khronos Group Inc.
|
||||
**
|
||||
** SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#if defined(_MSC_VER) && _MSC_VER < 1900 // Older than VS 2015.
|
||||
typedef unsigned __int32 VkFlags;
|
||||
#else
|
||||
#include <stdint.h>
|
||||
typedef uint32_t VkFlags;
|
||||
#endif
|
||||
|
||||
typedef enum VkFormat {
|
||||
VK_FORMAT_UNDEFINED = 0,
|
||||
VK_FORMAT_R4G4_UNORM_PACK8 = 1,
|
||||
VK_FORMAT_R4G4B4A4_UNORM_PACK16 = 2,
|
||||
VK_FORMAT_B4G4R4A4_UNORM_PACK16 = 3,
|
||||
VK_FORMAT_R5G6B5_UNORM_PACK16 = 4,
|
||||
VK_FORMAT_B5G6R5_UNORM_PACK16 = 5,
|
||||
VK_FORMAT_R5G5B5A1_UNORM_PACK16 = 6,
|
||||
VK_FORMAT_B5G5R5A1_UNORM_PACK16 = 7,
|
||||
VK_FORMAT_A1R5G5B5_UNORM_PACK16 = 8,
|
||||
VK_FORMAT_R8_UNORM = 9,
|
||||
VK_FORMAT_R8_SNORM = 10,
|
||||
VK_FORMAT_R8_USCALED = 11,
|
||||
VK_FORMAT_R8_SSCALED = 12,
|
||||
VK_FORMAT_R8_UINT = 13,
|
||||
VK_FORMAT_R8_SINT = 14,
|
||||
VK_FORMAT_R8_SRGB = 15,
|
||||
VK_FORMAT_R8G8_UNORM = 16,
|
||||
VK_FORMAT_R8G8_SNORM = 17,
|
||||
VK_FORMAT_R8G8_USCALED = 18,
|
||||
VK_FORMAT_R8G8_SSCALED = 19,
|
||||
VK_FORMAT_R8G8_UINT = 20,
|
||||
VK_FORMAT_R8G8_SINT = 21,
|
||||
VK_FORMAT_R8G8_SRGB = 22,
|
||||
VK_FORMAT_R8G8B8_UNORM = 23,
|
||||
VK_FORMAT_R8G8B8_SNORM = 24,
|
||||
VK_FORMAT_R8G8B8_USCALED = 25,
|
||||
VK_FORMAT_R8G8B8_SSCALED = 26,
|
||||
VK_FORMAT_R8G8B8_UINT = 27,
|
||||
VK_FORMAT_R8G8B8_SINT = 28,
|
||||
VK_FORMAT_R8G8B8_SRGB = 29,
|
||||
VK_FORMAT_B8G8R8_UNORM = 30,
|
||||
VK_FORMAT_B8G8R8_SNORM = 31,
|
||||
VK_FORMAT_B8G8R8_USCALED = 32,
|
||||
VK_FORMAT_B8G8R8_SSCALED = 33,
|
||||
VK_FORMAT_B8G8R8_UINT = 34,
|
||||
VK_FORMAT_B8G8R8_SINT = 35,
|
||||
VK_FORMAT_B8G8R8_SRGB = 36,
|
||||
VK_FORMAT_R8G8B8A8_UNORM = 37,
|
||||
VK_FORMAT_R8G8B8A8_SNORM = 38,
|
||||
VK_FORMAT_R8G8B8A8_USCALED = 39,
|
||||
VK_FORMAT_R8G8B8A8_SSCALED = 40,
|
||||
VK_FORMAT_R8G8B8A8_UINT = 41,
|
||||
VK_FORMAT_R8G8B8A8_SINT = 42,
|
||||
VK_FORMAT_R8G8B8A8_SRGB = 43,
|
||||
VK_FORMAT_B8G8R8A8_UNORM = 44,
|
||||
VK_FORMAT_B8G8R8A8_SNORM = 45,
|
||||
VK_FORMAT_B8G8R8A8_USCALED = 46,
|
||||
VK_FORMAT_B8G8R8A8_SSCALED = 47,
|
||||
VK_FORMAT_B8G8R8A8_UINT = 48,
|
||||
VK_FORMAT_B8G8R8A8_SINT = 49,
|
||||
VK_FORMAT_B8G8R8A8_SRGB = 50,
|
||||
VK_FORMAT_A8B8G8R8_UNORM_PACK32 = 51,
|
||||
VK_FORMAT_A8B8G8R8_SNORM_PACK32 = 52,
|
||||
VK_FORMAT_A8B8G8R8_USCALED_PACK32 = 53,
|
||||
VK_FORMAT_A8B8G8R8_SSCALED_PACK32 = 54,
|
||||
VK_FORMAT_A8B8G8R8_UINT_PACK32 = 55,
|
||||
VK_FORMAT_A8B8G8R8_SINT_PACK32 = 56,
|
||||
VK_FORMAT_A8B8G8R8_SRGB_PACK32 = 57,
|
||||
VK_FORMAT_A2R10G10B10_UNORM_PACK32 = 58,
|
||||
VK_FORMAT_A2R10G10B10_SNORM_PACK32 = 59,
|
||||
VK_FORMAT_A2R10G10B10_USCALED_PACK32 = 60,
|
||||
VK_FORMAT_A2R10G10B10_SSCALED_PACK32 = 61,
|
||||
VK_FORMAT_A2R10G10B10_UINT_PACK32 = 62,
|
||||
VK_FORMAT_A2R10G10B10_SINT_PACK32 = 63,
|
||||
VK_FORMAT_A2B10G10R10_UNORM_PACK32 = 64,
|
||||
VK_FORMAT_A2B10G10R10_SNORM_PACK32 = 65,
|
||||
VK_FORMAT_A2B10G10R10_USCALED_PACK32 = 66,
|
||||
VK_FORMAT_A2B10G10R10_SSCALED_PACK32 = 67,
|
||||
VK_FORMAT_A2B10G10R10_UINT_PACK32 = 68,
|
||||
VK_FORMAT_A2B10G10R10_SINT_PACK32 = 69,
|
||||
VK_FORMAT_R16_UNORM = 70,
|
||||
VK_FORMAT_R16_SNORM = 71,
|
||||
VK_FORMAT_R16_USCALED = 72,
|
||||
VK_FORMAT_R16_SSCALED = 73,
|
||||
VK_FORMAT_R16_UINT = 74,
|
||||
VK_FORMAT_R16_SINT = 75,
|
||||
VK_FORMAT_R16_SFLOAT = 76,
|
||||
VK_FORMAT_R16G16_UNORM = 77,
|
||||
VK_FORMAT_R16G16_SNORM = 78,
|
||||
VK_FORMAT_R16G16_USCALED = 79,
|
||||
VK_FORMAT_R16G16_SSCALED = 80,
|
||||
VK_FORMAT_R16G16_UINT = 81,
|
||||
VK_FORMAT_R16G16_SINT = 82,
|
||||
VK_FORMAT_R16G16_SFLOAT = 83,
|
||||
VK_FORMAT_R16G16B16_UNORM = 84,
|
||||
VK_FORMAT_R16G16B16_SNORM = 85,
|
||||
VK_FORMAT_R16G16B16_USCALED = 86,
|
||||
VK_FORMAT_R16G16B16_SSCALED = 87,
|
||||
VK_FORMAT_R16G16B16_UINT = 88,
|
||||
VK_FORMAT_R16G16B16_SINT = 89,
|
||||
VK_FORMAT_R16G16B16_SFLOAT = 90,
|
||||
VK_FORMAT_R16G16B16A16_UNORM = 91,
|
||||
VK_FORMAT_R16G16B16A16_SNORM = 92,
|
||||
VK_FORMAT_R16G16B16A16_USCALED = 93,
|
||||
VK_FORMAT_R16G16B16A16_SSCALED = 94,
|
||||
VK_FORMAT_R16G16B16A16_UINT = 95,
|
||||
VK_FORMAT_R16G16B16A16_SINT = 96,
|
||||
VK_FORMAT_R16G16B16A16_SFLOAT = 97,
|
||||
VK_FORMAT_R32_UINT = 98,
|
||||
VK_FORMAT_R32_SINT = 99,
|
||||
VK_FORMAT_R32_SFLOAT = 100,
|
||||
VK_FORMAT_R32G32_UINT = 101,
|
||||
VK_FORMAT_R32G32_SINT = 102,
|
||||
VK_FORMAT_R32G32_SFLOAT = 103,
|
||||
VK_FORMAT_R32G32B32_UINT = 104,
|
||||
VK_FORMAT_R32G32B32_SINT = 105,
|
||||
VK_FORMAT_R32G32B32_SFLOAT = 106,
|
||||
VK_FORMAT_R32G32B32A32_UINT = 107,
|
||||
VK_FORMAT_R32G32B32A32_SINT = 108,
|
||||
VK_FORMAT_R32G32B32A32_SFLOAT = 109,
|
||||
VK_FORMAT_R64_UINT = 110,
|
||||
VK_FORMAT_R64_SINT = 111,
|
||||
VK_FORMAT_R64_SFLOAT = 112,
|
||||
VK_FORMAT_R64G64_UINT = 113,
|
||||
VK_FORMAT_R64G64_SINT = 114,
|
||||
VK_FORMAT_R64G64_SFLOAT = 115,
|
||||
VK_FORMAT_R64G64B64_UINT = 116,
|
||||
VK_FORMAT_R64G64B64_SINT = 117,
|
||||
VK_FORMAT_R64G64B64_SFLOAT = 118,
|
||||
VK_FORMAT_R64G64B64A64_UINT = 119,
|
||||
VK_FORMAT_R64G64B64A64_SINT = 120,
|
||||
VK_FORMAT_R64G64B64A64_SFLOAT = 121,
|
||||
VK_FORMAT_B10G11R11_UFLOAT_PACK32 = 122,
|
||||
VK_FORMAT_E5B9G9R9_UFLOAT_PACK32 = 123,
|
||||
VK_FORMAT_D16_UNORM = 124,
|
||||
VK_FORMAT_X8_D24_UNORM_PACK32 = 125,
|
||||
VK_FORMAT_D32_SFLOAT = 126,
|
||||
VK_FORMAT_S8_UINT = 127,
|
||||
VK_FORMAT_D16_UNORM_S8_UINT = 128,
|
||||
VK_FORMAT_D24_UNORM_S8_UINT = 129,
|
||||
VK_FORMAT_D32_SFLOAT_S8_UINT = 130,
|
||||
VK_FORMAT_BC1_RGB_UNORM_BLOCK = 131,
|
||||
VK_FORMAT_BC1_RGB_SRGB_BLOCK = 132,
|
||||
VK_FORMAT_BC1_RGBA_UNORM_BLOCK = 133,
|
||||
VK_FORMAT_BC1_RGBA_SRGB_BLOCK = 134,
|
||||
VK_FORMAT_BC2_UNORM_BLOCK = 135,
|
||||
VK_FORMAT_BC2_SRGB_BLOCK = 136,
|
||||
VK_FORMAT_BC3_UNORM_BLOCK = 137,
|
||||
VK_FORMAT_BC3_SRGB_BLOCK = 138,
|
||||
VK_FORMAT_BC4_UNORM_BLOCK = 139,
|
||||
VK_FORMAT_BC4_SNORM_BLOCK = 140,
|
||||
VK_FORMAT_BC5_UNORM_BLOCK = 141,
|
||||
VK_FORMAT_BC5_SNORM_BLOCK = 142,
|
||||
VK_FORMAT_BC6H_UFLOAT_BLOCK = 143,
|
||||
VK_FORMAT_BC6H_SFLOAT_BLOCK = 144,
|
||||
VK_FORMAT_BC7_UNORM_BLOCK = 145,
|
||||
VK_FORMAT_BC7_SRGB_BLOCK = 146,
|
||||
VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK = 147,
|
||||
VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK = 148,
|
||||
VK_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK = 149,
|
||||
VK_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK = 150,
|
||||
VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK = 151,
|
||||
VK_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK = 152,
|
||||
VK_FORMAT_EAC_R11_UNORM_BLOCK = 153,
|
||||
VK_FORMAT_EAC_R11_SNORM_BLOCK = 154,
|
||||
VK_FORMAT_EAC_R11G11_UNORM_BLOCK = 155,
|
||||
VK_FORMAT_EAC_R11G11_SNORM_BLOCK = 156,
|
||||
VK_FORMAT_ASTC_4x4_UNORM_BLOCK = 157,
|
||||
VK_FORMAT_ASTC_4x4_SRGB_BLOCK = 158,
|
||||
VK_FORMAT_ASTC_5x4_UNORM_BLOCK = 159,
|
||||
VK_FORMAT_ASTC_5x4_SRGB_BLOCK = 160,
|
||||
VK_FORMAT_ASTC_5x5_UNORM_BLOCK = 161,
|
||||
VK_FORMAT_ASTC_5x5_SRGB_BLOCK = 162,
|
||||
VK_FORMAT_ASTC_6x5_UNORM_BLOCK = 163,
|
||||
VK_FORMAT_ASTC_6x5_SRGB_BLOCK = 164,
|
||||
VK_FORMAT_ASTC_6x6_UNORM_BLOCK = 165,
|
||||
VK_FORMAT_ASTC_6x6_SRGB_BLOCK = 166,
|
||||
VK_FORMAT_ASTC_8x5_UNORM_BLOCK = 167,
|
||||
VK_FORMAT_ASTC_8x5_SRGB_BLOCK = 168,
|
||||
VK_FORMAT_ASTC_8x6_UNORM_BLOCK = 169,
|
||||
VK_FORMAT_ASTC_8x6_SRGB_BLOCK = 170,
|
||||
VK_FORMAT_ASTC_8x8_UNORM_BLOCK = 171,
|
||||
VK_FORMAT_ASTC_8x8_SRGB_BLOCK = 172,
|
||||
VK_FORMAT_ASTC_10x5_UNORM_BLOCK = 173,
|
||||
VK_FORMAT_ASTC_10x5_SRGB_BLOCK = 174,
|
||||
VK_FORMAT_ASTC_10x6_UNORM_BLOCK = 175,
|
||||
VK_FORMAT_ASTC_10x6_SRGB_BLOCK = 176,
|
||||
VK_FORMAT_ASTC_10x8_UNORM_BLOCK = 177,
|
||||
VK_FORMAT_ASTC_10x8_SRGB_BLOCK = 178,
|
||||
VK_FORMAT_ASTC_10x10_UNORM_BLOCK = 179,
|
||||
VK_FORMAT_ASTC_10x10_SRGB_BLOCK = 180,
|
||||
VK_FORMAT_ASTC_12x10_UNORM_BLOCK = 181,
|
||||
VK_FORMAT_ASTC_12x10_SRGB_BLOCK = 182,
|
||||
VK_FORMAT_ASTC_12x12_UNORM_BLOCK = 183,
|
||||
VK_FORMAT_ASTC_12x12_SRGB_BLOCK = 184,
|
||||
VK_FORMAT_G8B8G8R8_422_UNORM = 1000156000,
|
||||
VK_FORMAT_B8G8R8G8_422_UNORM = 1000156001,
|
||||
VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM = 1000156002,
|
||||
VK_FORMAT_G8_B8R8_2PLANE_420_UNORM = 1000156003,
|
||||
VK_FORMAT_G8_B8_R8_3PLANE_422_UNORM = 1000156004,
|
||||
VK_FORMAT_G8_B8R8_2PLANE_422_UNORM = 1000156005,
|
||||
VK_FORMAT_G8_B8_R8_3PLANE_444_UNORM = 1000156006,
|
||||
VK_FORMAT_R10X6_UNORM_PACK16 = 1000156007,
|
||||
VK_FORMAT_R10X6G10X6_UNORM_2PACK16 = 1000156008,
|
||||
VK_FORMAT_R10X6G10X6B10X6A10X6_UNORM_4PACK16 = 1000156009,
|
||||
VK_FORMAT_G10X6B10X6G10X6R10X6_422_UNORM_4PACK16 = 1000156010,
|
||||
VK_FORMAT_B10X6G10X6R10X6G10X6_422_UNORM_4PACK16 = 1000156011,
|
||||
VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_420_UNORM_3PACK16 = 1000156012,
|
||||
VK_FORMAT_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16 = 1000156013,
|
||||
VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_422_UNORM_3PACK16 = 1000156014,
|
||||
VK_FORMAT_G10X6_B10X6R10X6_2PLANE_422_UNORM_3PACK16 = 1000156015,
|
||||
VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_444_UNORM_3PACK16 = 1000156016,
|
||||
VK_FORMAT_R12X4_UNORM_PACK16 = 1000156017,
|
||||
VK_FORMAT_R12X4G12X4_UNORM_2PACK16 = 1000156018,
|
||||
VK_FORMAT_R12X4G12X4B12X4A12X4_UNORM_4PACK16 = 1000156019,
|
||||
VK_FORMAT_G12X4B12X4G12X4R12X4_422_UNORM_4PACK16 = 1000156020,
|
||||
VK_FORMAT_B12X4G12X4R12X4G12X4_422_UNORM_4PACK16 = 1000156021,
|
||||
VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_420_UNORM_3PACK16 = 1000156022,
|
||||
VK_FORMAT_G12X4_B12X4R12X4_2PLANE_420_UNORM_3PACK16 = 1000156023,
|
||||
VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_422_UNORM_3PACK16 = 1000156024,
|
||||
VK_FORMAT_G12X4_B12X4R12X4_2PLANE_422_UNORM_3PACK16 = 1000156025,
|
||||
VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_444_UNORM_3PACK16 = 1000156026,
|
||||
VK_FORMAT_G16B16G16R16_422_UNORM = 1000156027,
|
||||
VK_FORMAT_B16G16R16G16_422_UNORM = 1000156028,
|
||||
VK_FORMAT_G16_B16_R16_3PLANE_420_UNORM = 1000156029,
|
||||
VK_FORMAT_G16_B16R16_2PLANE_420_UNORM = 1000156030,
|
||||
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,
|
||||
VK_FORMAT_PVRTC2_4BPP_UNORM_BLOCK_IMG = 1000054003,
|
||||
VK_FORMAT_PVRTC1_2BPP_SRGB_BLOCK_IMG = 1000054004,
|
||||
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_3x3x3_UNORM_BLOCK_EXT = 1000288000,
|
||||
VK_FORMAT_ASTC_3x3x3_SRGB_BLOCK_EXT = 1000288001,
|
||||
VK_FORMAT_ASTC_3x3x3_SFLOAT_BLOCK_EXT = 1000288002,
|
||||
VK_FORMAT_ASTC_4x3x3_UNORM_BLOCK_EXT = 1000288003,
|
||||
VK_FORMAT_ASTC_4x3x3_SRGB_BLOCK_EXT = 1000288004,
|
||||
VK_FORMAT_ASTC_4x3x3_SFLOAT_BLOCK_EXT = 1000288005,
|
||||
VK_FORMAT_ASTC_4x4x3_UNORM_BLOCK_EXT = 1000288006,
|
||||
VK_FORMAT_ASTC_4x4x3_SRGB_BLOCK_EXT = 1000288007,
|
||||
VK_FORMAT_ASTC_4x4x3_SFLOAT_BLOCK_EXT = 1000288008,
|
||||
VK_FORMAT_ASTC_4x4x4_UNORM_BLOCK_EXT = 1000288009,
|
||||
VK_FORMAT_ASTC_4x4x4_SRGB_BLOCK_EXT = 1000288010,
|
||||
VK_FORMAT_ASTC_4x4x4_SFLOAT_BLOCK_EXT = 1000288011,
|
||||
VK_FORMAT_ASTC_5x4x4_UNORM_BLOCK_EXT = 1000288012,
|
||||
VK_FORMAT_ASTC_5x4x4_SRGB_BLOCK_EXT = 1000288013,
|
||||
VK_FORMAT_ASTC_5x4x4_SFLOAT_BLOCK_EXT = 1000288014,
|
||||
VK_FORMAT_ASTC_5x5x4_UNORM_BLOCK_EXT = 1000288015,
|
||||
VK_FORMAT_ASTC_5x5x4_SRGB_BLOCK_EXT = 1000288016,
|
||||
VK_FORMAT_ASTC_5x5x4_SFLOAT_BLOCK_EXT = 1000288017,
|
||||
VK_FORMAT_ASTC_5x5x5_UNORM_BLOCK_EXT = 1000288018,
|
||||
VK_FORMAT_ASTC_5x5x5_SRGB_BLOCK_EXT = 1000288019,
|
||||
VK_FORMAT_ASTC_5x5x5_SFLOAT_BLOCK_EXT = 1000288020,
|
||||
VK_FORMAT_ASTC_6x5x5_UNORM_BLOCK_EXT = 1000288021,
|
||||
VK_FORMAT_ASTC_6x5x5_SRGB_BLOCK_EXT = 1000288022,
|
||||
VK_FORMAT_ASTC_6x5x5_SFLOAT_BLOCK_EXT = 1000288023,
|
||||
VK_FORMAT_ASTC_6x6x5_UNORM_BLOCK_EXT = 1000288024,
|
||||
VK_FORMAT_ASTC_6x6x5_SRGB_BLOCK_EXT = 1000288025,
|
||||
VK_FORMAT_ASTC_6x6x5_SFLOAT_BLOCK_EXT = 1000288026,
|
||||
VK_FORMAT_ASTC_6x6x6_UNORM_BLOCK_EXT = 1000288027,
|
||||
VK_FORMAT_ASTC_6x6x6_SRGB_BLOCK_EXT = 1000288028,
|
||||
VK_FORMAT_ASTC_6x6x6_SFLOAT_BLOCK_EXT = 1000288029,
|
||||
VK_FORMAT_R16G16_SFIXED5_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
|
||||
|
||||
#endif /* _VKFORMAT_ENUM_H_ */
|
||||
// clang-format on
|
586
thirdparty/libktx/lib/vkformat_typesize.c
vendored
Normal file
586
thirdparty/libktx/lib/vkformat_typesize.c
vendored
Normal file
@@ -0,0 +1,586 @@
|
||||
|
||||
/***************************** Do not edit. *****************************
|
||||
Automatically generated from vulkan_core.h version 287 by mkvkformatfiles.
|
||||
*************************************************************************/
|
||||
|
||||
/*
|
||||
** Copyright 2015-2024 The Khronos Group Inc.
|
||||
**
|
||||
** SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
// clang-format off: CI is complicated if formatting checks on generated files are enforced.
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "vkformat_enum.h"
|
||||
|
||||
uint32_t
|
||||
vkFormatTypeSize(VkFormat format)
|
||||
{
|
||||
switch (format) {
|
||||
case VK_FORMAT_UNDEFINED:
|
||||
return 1;
|
||||
case VK_FORMAT_R4G4_UNORM_PACK8:
|
||||
return 1;
|
||||
case VK_FORMAT_R4G4B4A4_UNORM_PACK16:
|
||||
return 2;
|
||||
case VK_FORMAT_B4G4R4A4_UNORM_PACK16:
|
||||
return 2;
|
||||
case VK_FORMAT_R5G6B5_UNORM_PACK16:
|
||||
return 2;
|
||||
case VK_FORMAT_B5G6R5_UNORM_PACK16:
|
||||
return 2;
|
||||
case VK_FORMAT_R5G5B5A1_UNORM_PACK16:
|
||||
return 2;
|
||||
case VK_FORMAT_B5G5R5A1_UNORM_PACK16:
|
||||
return 2;
|
||||
case VK_FORMAT_A1R5G5B5_UNORM_PACK16:
|
||||
return 2;
|
||||
case VK_FORMAT_R8_UNORM:
|
||||
return 1;
|
||||
case VK_FORMAT_R8_SNORM:
|
||||
return 1;
|
||||
case VK_FORMAT_R8_USCALED:
|
||||
return 1;
|
||||
case VK_FORMAT_R8_SSCALED:
|
||||
return 1;
|
||||
case VK_FORMAT_R8_UINT:
|
||||
return 1;
|
||||
case VK_FORMAT_R8_SINT:
|
||||
return 1;
|
||||
case VK_FORMAT_R8_SRGB:
|
||||
return 1;
|
||||
case VK_FORMAT_R8G8_UNORM:
|
||||
return 1;
|
||||
case VK_FORMAT_R8G8_SNORM:
|
||||
return 1;
|
||||
case VK_FORMAT_R8G8_USCALED:
|
||||
return 1;
|
||||
case VK_FORMAT_R8G8_SSCALED:
|
||||
return 1;
|
||||
case VK_FORMAT_R8G8_UINT:
|
||||
return 1;
|
||||
case VK_FORMAT_R8G8_SINT:
|
||||
return 1;
|
||||
case VK_FORMAT_R8G8_SRGB:
|
||||
return 1;
|
||||
case VK_FORMAT_R8G8B8_UNORM:
|
||||
return 1;
|
||||
case VK_FORMAT_R8G8B8_SNORM:
|
||||
return 1;
|
||||
case VK_FORMAT_R8G8B8_USCALED:
|
||||
return 1;
|
||||
case VK_FORMAT_R8G8B8_SSCALED:
|
||||
return 1;
|
||||
case VK_FORMAT_R8G8B8_UINT:
|
||||
return 1;
|
||||
case VK_FORMAT_R8G8B8_SINT:
|
||||
return 1;
|
||||
case VK_FORMAT_R8G8B8_SRGB:
|
||||
return 1;
|
||||
case VK_FORMAT_B8G8R8_UNORM:
|
||||
return 1;
|
||||
case VK_FORMAT_B8G8R8_SNORM:
|
||||
return 1;
|
||||
case VK_FORMAT_B8G8R8_USCALED:
|
||||
return 1;
|
||||
case VK_FORMAT_B8G8R8_SSCALED:
|
||||
return 1;
|
||||
case VK_FORMAT_B8G8R8_UINT:
|
||||
return 1;
|
||||
case VK_FORMAT_B8G8R8_SINT:
|
||||
return 1;
|
||||
case VK_FORMAT_B8G8R8_SRGB:
|
||||
return 1;
|
||||
case VK_FORMAT_R8G8B8A8_UNORM:
|
||||
return 1;
|
||||
case VK_FORMAT_R8G8B8A8_SNORM:
|
||||
return 1;
|
||||
case VK_FORMAT_R8G8B8A8_USCALED:
|
||||
return 1;
|
||||
case VK_FORMAT_R8G8B8A8_SSCALED:
|
||||
return 1;
|
||||
case VK_FORMAT_R8G8B8A8_UINT:
|
||||
return 1;
|
||||
case VK_FORMAT_R8G8B8A8_SINT:
|
||||
return 1;
|
||||
case VK_FORMAT_R8G8B8A8_SRGB:
|
||||
return 1;
|
||||
case VK_FORMAT_B8G8R8A8_UNORM:
|
||||
return 1;
|
||||
case VK_FORMAT_B8G8R8A8_SNORM:
|
||||
return 1;
|
||||
case VK_FORMAT_B8G8R8A8_USCALED:
|
||||
return 1;
|
||||
case VK_FORMAT_B8G8R8A8_SSCALED:
|
||||
return 1;
|
||||
case VK_FORMAT_B8G8R8A8_UINT:
|
||||
return 1;
|
||||
case VK_FORMAT_B8G8R8A8_SINT:
|
||||
return 1;
|
||||
case VK_FORMAT_B8G8R8A8_SRGB:
|
||||
return 1;
|
||||
case VK_FORMAT_A8B8G8R8_UNORM_PACK32:
|
||||
return 4;
|
||||
case VK_FORMAT_A8B8G8R8_SNORM_PACK32:
|
||||
return 4;
|
||||
case VK_FORMAT_A8B8G8R8_USCALED_PACK32:
|
||||
return 4;
|
||||
case VK_FORMAT_A8B8G8R8_SSCALED_PACK32:
|
||||
return 4;
|
||||
case VK_FORMAT_A8B8G8R8_UINT_PACK32:
|
||||
return 4;
|
||||
case VK_FORMAT_A8B8G8R8_SINT_PACK32:
|
||||
return 4;
|
||||
case VK_FORMAT_A8B8G8R8_SRGB_PACK32:
|
||||
return 4;
|
||||
case VK_FORMAT_A2R10G10B10_UNORM_PACK32:
|
||||
return 4;
|
||||
case VK_FORMAT_A2R10G10B10_SNORM_PACK32:
|
||||
return 4;
|
||||
case VK_FORMAT_A2R10G10B10_USCALED_PACK32:
|
||||
return 4;
|
||||
case VK_FORMAT_A2R10G10B10_SSCALED_PACK32:
|
||||
return 4;
|
||||
case VK_FORMAT_A2R10G10B10_UINT_PACK32:
|
||||
return 4;
|
||||
case VK_FORMAT_A2R10G10B10_SINT_PACK32:
|
||||
return 4;
|
||||
case VK_FORMAT_A2B10G10R10_UNORM_PACK32:
|
||||
return 4;
|
||||
case VK_FORMAT_A2B10G10R10_SNORM_PACK32:
|
||||
return 4;
|
||||
case VK_FORMAT_A2B10G10R10_USCALED_PACK32:
|
||||
return 4;
|
||||
case VK_FORMAT_A2B10G10R10_SSCALED_PACK32:
|
||||
return 4;
|
||||
case VK_FORMAT_A2B10G10R10_UINT_PACK32:
|
||||
return 4;
|
||||
case VK_FORMAT_A2B10G10R10_SINT_PACK32:
|
||||
return 4;
|
||||
case VK_FORMAT_R16_UNORM:
|
||||
return 2;
|
||||
case VK_FORMAT_R16_SNORM:
|
||||
return 2;
|
||||
case VK_FORMAT_R16_USCALED:
|
||||
return 2;
|
||||
case VK_FORMAT_R16_SSCALED:
|
||||
return 2;
|
||||
case VK_FORMAT_R16_UINT:
|
||||
return 2;
|
||||
case VK_FORMAT_R16_SINT:
|
||||
return 2;
|
||||
case VK_FORMAT_R16_SFLOAT:
|
||||
return 2;
|
||||
case VK_FORMAT_R16G16_UNORM:
|
||||
return 2;
|
||||
case VK_FORMAT_R16G16_SNORM:
|
||||
return 2;
|
||||
case VK_FORMAT_R16G16_USCALED:
|
||||
return 2;
|
||||
case VK_FORMAT_R16G16_SSCALED:
|
||||
return 2;
|
||||
case VK_FORMAT_R16G16_UINT:
|
||||
return 2;
|
||||
case VK_FORMAT_R16G16_SINT:
|
||||
return 2;
|
||||
case VK_FORMAT_R16G16_SFLOAT:
|
||||
return 2;
|
||||
case VK_FORMAT_R16G16B16_UNORM:
|
||||
return 2;
|
||||
case VK_FORMAT_R16G16B16_SNORM:
|
||||
return 2;
|
||||
case VK_FORMAT_R16G16B16_USCALED:
|
||||
return 2;
|
||||
case VK_FORMAT_R16G16B16_SSCALED:
|
||||
return 2;
|
||||
case VK_FORMAT_R16G16B16_UINT:
|
||||
return 2;
|
||||
case VK_FORMAT_R16G16B16_SINT:
|
||||
return 2;
|
||||
case VK_FORMAT_R16G16B16_SFLOAT:
|
||||
return 2;
|
||||
case VK_FORMAT_R16G16B16A16_UNORM:
|
||||
return 2;
|
||||
case VK_FORMAT_R16G16B16A16_SNORM:
|
||||
return 2;
|
||||
case VK_FORMAT_R16G16B16A16_USCALED:
|
||||
return 2;
|
||||
case VK_FORMAT_R16G16B16A16_SSCALED:
|
||||
return 2;
|
||||
case VK_FORMAT_R16G16B16A16_UINT:
|
||||
return 2;
|
||||
case VK_FORMAT_R16G16B16A16_SINT:
|
||||
return 2;
|
||||
case VK_FORMAT_R16G16B16A16_SFLOAT:
|
||||
return 2;
|
||||
case VK_FORMAT_R32_UINT:
|
||||
return 4;
|
||||
case VK_FORMAT_R32_SINT:
|
||||
return 4;
|
||||
case VK_FORMAT_R32_SFLOAT:
|
||||
return 4;
|
||||
case VK_FORMAT_R32G32_UINT:
|
||||
return 4;
|
||||
case VK_FORMAT_R32G32_SINT:
|
||||
return 4;
|
||||
case VK_FORMAT_R32G32_SFLOAT:
|
||||
return 4;
|
||||
case VK_FORMAT_R32G32B32_UINT:
|
||||
return 4;
|
||||
case VK_FORMAT_R32G32B32_SINT:
|
||||
return 4;
|
||||
case VK_FORMAT_R32G32B32_SFLOAT:
|
||||
return 4;
|
||||
case VK_FORMAT_R32G32B32A32_UINT:
|
||||
return 4;
|
||||
case VK_FORMAT_R32G32B32A32_SINT:
|
||||
return 4;
|
||||
case VK_FORMAT_R32G32B32A32_SFLOAT:
|
||||
return 4;
|
||||
case VK_FORMAT_R64_UINT:
|
||||
return 8;
|
||||
case VK_FORMAT_R64_SINT:
|
||||
return 8;
|
||||
case VK_FORMAT_R64_SFLOAT:
|
||||
return 8;
|
||||
case VK_FORMAT_R64G64_UINT:
|
||||
return 8;
|
||||
case VK_FORMAT_R64G64_SINT:
|
||||
return 8;
|
||||
case VK_FORMAT_R64G64_SFLOAT:
|
||||
return 8;
|
||||
case VK_FORMAT_R64G64B64_UINT:
|
||||
return 8;
|
||||
case VK_FORMAT_R64G64B64_SINT:
|
||||
return 8;
|
||||
case VK_FORMAT_R64G64B64_SFLOAT:
|
||||
return 8;
|
||||
case VK_FORMAT_R64G64B64A64_UINT:
|
||||
return 8;
|
||||
case VK_FORMAT_R64G64B64A64_SINT:
|
||||
return 8;
|
||||
case VK_FORMAT_R64G64B64A64_SFLOAT:
|
||||
return 8;
|
||||
case VK_FORMAT_B10G11R11_UFLOAT_PACK32:
|
||||
return 4;
|
||||
case VK_FORMAT_E5B9G9R9_UFLOAT_PACK32:
|
||||
return 4;
|
||||
case VK_FORMAT_D16_UNORM:
|
||||
return 2;
|
||||
case VK_FORMAT_X8_D24_UNORM_PACK32:
|
||||
return 4;
|
||||
case VK_FORMAT_D32_SFLOAT:
|
||||
return 4;
|
||||
case VK_FORMAT_S8_UINT:
|
||||
return 1;
|
||||
case VK_FORMAT_D16_UNORM_S8_UINT:
|
||||
return 2;
|
||||
case VK_FORMAT_D24_UNORM_S8_UINT:
|
||||
return 4;
|
||||
case VK_FORMAT_D32_SFLOAT_S8_UINT:
|
||||
return 4;
|
||||
case VK_FORMAT_BC1_RGB_UNORM_BLOCK:
|
||||
return 1;
|
||||
case VK_FORMAT_BC1_RGB_SRGB_BLOCK:
|
||||
return 1;
|
||||
case VK_FORMAT_BC1_RGBA_UNORM_BLOCK:
|
||||
return 1;
|
||||
case VK_FORMAT_BC1_RGBA_SRGB_BLOCK:
|
||||
return 1;
|
||||
case VK_FORMAT_BC2_UNORM_BLOCK:
|
||||
return 1;
|
||||
case VK_FORMAT_BC2_SRGB_BLOCK:
|
||||
return 1;
|
||||
case VK_FORMAT_BC3_UNORM_BLOCK:
|
||||
return 1;
|
||||
case VK_FORMAT_BC3_SRGB_BLOCK:
|
||||
return 1;
|
||||
case VK_FORMAT_BC4_UNORM_BLOCK:
|
||||
return 1;
|
||||
case VK_FORMAT_BC4_SNORM_BLOCK:
|
||||
return 1;
|
||||
case VK_FORMAT_BC5_UNORM_BLOCK:
|
||||
return 1;
|
||||
case VK_FORMAT_BC5_SNORM_BLOCK:
|
||||
return 1;
|
||||
case VK_FORMAT_BC6H_UFLOAT_BLOCK:
|
||||
return 1;
|
||||
case VK_FORMAT_BC6H_SFLOAT_BLOCK:
|
||||
return 1;
|
||||
case VK_FORMAT_BC7_UNORM_BLOCK:
|
||||
return 1;
|
||||
case VK_FORMAT_BC7_SRGB_BLOCK:
|
||||
return 1;
|
||||
case VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK:
|
||||
return 1;
|
||||
case VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK:
|
||||
return 1;
|
||||
case VK_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK:
|
||||
return 1;
|
||||
case VK_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK:
|
||||
return 1;
|
||||
case VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK:
|
||||
return 1;
|
||||
case VK_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK:
|
||||
return 1;
|
||||
case VK_FORMAT_EAC_R11_UNORM_BLOCK:
|
||||
return 1;
|
||||
case VK_FORMAT_EAC_R11_SNORM_BLOCK:
|
||||
return 1;
|
||||
case VK_FORMAT_EAC_R11G11_UNORM_BLOCK:
|
||||
return 1;
|
||||
case VK_FORMAT_EAC_R11G11_SNORM_BLOCK:
|
||||
return 1;
|
||||
case VK_FORMAT_ASTC_4x4_UNORM_BLOCK:
|
||||
return 1;
|
||||
case VK_FORMAT_ASTC_4x4_SRGB_BLOCK:
|
||||
return 1;
|
||||
case VK_FORMAT_ASTC_5x4_UNORM_BLOCK:
|
||||
return 1;
|
||||
case VK_FORMAT_ASTC_5x4_SRGB_BLOCK:
|
||||
return 1;
|
||||
case VK_FORMAT_ASTC_5x5_UNORM_BLOCK:
|
||||
return 1;
|
||||
case VK_FORMAT_ASTC_5x5_SRGB_BLOCK:
|
||||
return 1;
|
||||
case VK_FORMAT_ASTC_6x5_UNORM_BLOCK:
|
||||
return 1;
|
||||
case VK_FORMAT_ASTC_6x5_SRGB_BLOCK:
|
||||
return 1;
|
||||
case VK_FORMAT_ASTC_6x6_UNORM_BLOCK:
|
||||
return 1;
|
||||
case VK_FORMAT_ASTC_6x6_SRGB_BLOCK:
|
||||
return 1;
|
||||
case VK_FORMAT_ASTC_8x5_UNORM_BLOCK:
|
||||
return 1;
|
||||
case VK_FORMAT_ASTC_8x5_SRGB_BLOCK:
|
||||
return 1;
|
||||
case VK_FORMAT_ASTC_8x6_UNORM_BLOCK:
|
||||
return 1;
|
||||
case VK_FORMAT_ASTC_8x6_SRGB_BLOCK:
|
||||
return 1;
|
||||
case VK_FORMAT_ASTC_8x8_UNORM_BLOCK:
|
||||
return 1;
|
||||
case VK_FORMAT_ASTC_8x8_SRGB_BLOCK:
|
||||
return 1;
|
||||
case VK_FORMAT_ASTC_10x5_UNORM_BLOCK:
|
||||
return 1;
|
||||
case VK_FORMAT_ASTC_10x5_SRGB_BLOCK:
|
||||
return 1;
|
||||
case VK_FORMAT_ASTC_10x6_UNORM_BLOCK:
|
||||
return 1;
|
||||
case VK_FORMAT_ASTC_10x6_SRGB_BLOCK:
|
||||
return 1;
|
||||
case VK_FORMAT_ASTC_10x8_UNORM_BLOCK:
|
||||
return 1;
|
||||
case VK_FORMAT_ASTC_10x8_SRGB_BLOCK:
|
||||
return 1;
|
||||
case VK_FORMAT_ASTC_10x10_UNORM_BLOCK:
|
||||
return 1;
|
||||
case VK_FORMAT_ASTC_10x10_SRGB_BLOCK:
|
||||
return 1;
|
||||
case VK_FORMAT_ASTC_12x10_UNORM_BLOCK:
|
||||
return 1;
|
||||
case VK_FORMAT_ASTC_12x10_SRGB_BLOCK:
|
||||
return 1;
|
||||
case VK_FORMAT_ASTC_12x12_UNORM_BLOCK:
|
||||
return 1;
|
||||
case VK_FORMAT_ASTC_12x12_SRGB_BLOCK:
|
||||
return 1;
|
||||
case VK_FORMAT_G8B8G8R8_422_UNORM:
|
||||
return 1;
|
||||
case VK_FORMAT_B8G8R8G8_422_UNORM:
|
||||
return 1;
|
||||
case VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM:
|
||||
return 1;
|
||||
case VK_FORMAT_G8_B8R8_2PLANE_420_UNORM:
|
||||
return 1;
|
||||
case VK_FORMAT_G8_B8_R8_3PLANE_422_UNORM:
|
||||
return 1;
|
||||
case VK_FORMAT_G8_B8R8_2PLANE_422_UNORM:
|
||||
return 1;
|
||||
case VK_FORMAT_G8_B8_R8_3PLANE_444_UNORM:
|
||||
return 1;
|
||||
case VK_FORMAT_R10X6_UNORM_PACK16:
|
||||
return 2;
|
||||
case VK_FORMAT_R10X6G10X6_UNORM_2PACK16:
|
||||
return 2;
|
||||
case VK_FORMAT_R10X6G10X6B10X6A10X6_UNORM_4PACK16:
|
||||
return 2;
|
||||
case VK_FORMAT_G10X6B10X6G10X6R10X6_422_UNORM_4PACK16:
|
||||
return 2;
|
||||
case VK_FORMAT_B10X6G10X6R10X6G10X6_422_UNORM_4PACK16:
|
||||
return 2;
|
||||
case VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_420_UNORM_3PACK16:
|
||||
return 2;
|
||||
case VK_FORMAT_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16:
|
||||
return 2;
|
||||
case VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_422_UNORM_3PACK16:
|
||||
return 2;
|
||||
case VK_FORMAT_G10X6_B10X6R10X6_2PLANE_422_UNORM_3PACK16:
|
||||
return 2;
|
||||
case VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_444_UNORM_3PACK16:
|
||||
return 2;
|
||||
case VK_FORMAT_R12X4_UNORM_PACK16:
|
||||
return 2;
|
||||
case VK_FORMAT_R12X4G12X4_UNORM_2PACK16:
|
||||
return 2;
|
||||
case VK_FORMAT_R12X4G12X4B12X4A12X4_UNORM_4PACK16:
|
||||
return 2;
|
||||
case VK_FORMAT_G12X4B12X4G12X4R12X4_422_UNORM_4PACK16:
|
||||
return 2;
|
||||
case VK_FORMAT_B12X4G12X4R12X4G12X4_422_UNORM_4PACK16:
|
||||
return 2;
|
||||
case VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_420_UNORM_3PACK16:
|
||||
return 2;
|
||||
case VK_FORMAT_G12X4_B12X4R12X4_2PLANE_420_UNORM_3PACK16:
|
||||
return 2;
|
||||
case VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_422_UNORM_3PACK16:
|
||||
return 2;
|
||||
case VK_FORMAT_G12X4_B12X4R12X4_2PLANE_422_UNORM_3PACK16:
|
||||
return 2;
|
||||
case VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_444_UNORM_3PACK16:
|
||||
return 2;
|
||||
case VK_FORMAT_G16B16G16R16_422_UNORM:
|
||||
return 2;
|
||||
case VK_FORMAT_B16G16R16G16_422_UNORM:
|
||||
return 2;
|
||||
case VK_FORMAT_G16_B16_R16_3PLANE_420_UNORM:
|
||||
return 2;
|
||||
case VK_FORMAT_G16_B16R16_2PLANE_420_UNORM:
|
||||
return 2;
|
||||
case VK_FORMAT_G16_B16_R16_3PLANE_422_UNORM:
|
||||
return 2;
|
||||
case VK_FORMAT_G16_B16R16_2PLANE_422_UNORM:
|
||||
return 2;
|
||||
case VK_FORMAT_G16_B16_R16_3PLANE_444_UNORM:
|
||||
return 2;
|
||||
case VK_FORMAT_G8_B8R8_2PLANE_444_UNORM:
|
||||
return 1;
|
||||
case VK_FORMAT_G10X6_B10X6R10X6_2PLANE_444_UNORM_3PACK16:
|
||||
return 2;
|
||||
case VK_FORMAT_G12X4_B12X4R12X4_2PLANE_444_UNORM_3PACK16:
|
||||
return 2;
|
||||
case VK_FORMAT_G16_B16R16_2PLANE_444_UNORM:
|
||||
return 2;
|
||||
case VK_FORMAT_A4R4G4B4_UNORM_PACK16:
|
||||
return 2;
|
||||
case VK_FORMAT_A4B4G4R4_UNORM_PACK16:
|
||||
return 2;
|
||||
case VK_FORMAT_ASTC_4x4_SFLOAT_BLOCK:
|
||||
return 1;
|
||||
case VK_FORMAT_ASTC_5x4_SFLOAT_BLOCK:
|
||||
return 1;
|
||||
case VK_FORMAT_ASTC_5x5_SFLOAT_BLOCK:
|
||||
return 1;
|
||||
case VK_FORMAT_ASTC_6x5_SFLOAT_BLOCK:
|
||||
return 1;
|
||||
case VK_FORMAT_ASTC_6x6_SFLOAT_BLOCK:
|
||||
return 1;
|
||||
case VK_FORMAT_ASTC_8x5_SFLOAT_BLOCK:
|
||||
return 1;
|
||||
case VK_FORMAT_ASTC_8x6_SFLOAT_BLOCK:
|
||||
return 1;
|
||||
case VK_FORMAT_ASTC_8x8_SFLOAT_BLOCK:
|
||||
return 1;
|
||||
case VK_FORMAT_ASTC_10x5_SFLOAT_BLOCK:
|
||||
return 1;
|
||||
case VK_FORMAT_ASTC_10x6_SFLOAT_BLOCK:
|
||||
return 1;
|
||||
case VK_FORMAT_ASTC_10x8_SFLOAT_BLOCK:
|
||||
return 1;
|
||||
case VK_FORMAT_ASTC_10x10_SFLOAT_BLOCK:
|
||||
return 1;
|
||||
case VK_FORMAT_ASTC_12x10_SFLOAT_BLOCK:
|
||||
return 1;
|
||||
case VK_FORMAT_ASTC_12x12_SFLOAT_BLOCK:
|
||||
return 1;
|
||||
case VK_FORMAT_PVRTC1_2BPP_UNORM_BLOCK_IMG:
|
||||
return 1;
|
||||
case VK_FORMAT_PVRTC1_4BPP_UNORM_BLOCK_IMG:
|
||||
return 1;
|
||||
case VK_FORMAT_PVRTC2_2BPP_UNORM_BLOCK_IMG:
|
||||
return 1;
|
||||
case VK_FORMAT_PVRTC2_4BPP_UNORM_BLOCK_IMG:
|
||||
return 1;
|
||||
case VK_FORMAT_PVRTC1_2BPP_SRGB_BLOCK_IMG:
|
||||
return 1;
|
||||
case VK_FORMAT_PVRTC1_4BPP_SRGB_BLOCK_IMG:
|
||||
return 1;
|
||||
case VK_FORMAT_PVRTC2_2BPP_SRGB_BLOCK_IMG:
|
||||
return 1;
|
||||
case VK_FORMAT_PVRTC2_4BPP_SRGB_BLOCK_IMG:
|
||||
return 1;
|
||||
case VK_FORMAT_ASTC_3x3x3_UNORM_BLOCK_EXT:
|
||||
return 1;
|
||||
case VK_FORMAT_ASTC_3x3x3_SRGB_BLOCK_EXT:
|
||||
return 1;
|
||||
case VK_FORMAT_ASTC_3x3x3_SFLOAT_BLOCK_EXT:
|
||||
return 1;
|
||||
case VK_FORMAT_ASTC_4x3x3_UNORM_BLOCK_EXT:
|
||||
return 1;
|
||||
case VK_FORMAT_ASTC_4x3x3_SRGB_BLOCK_EXT:
|
||||
return 1;
|
||||
case VK_FORMAT_ASTC_4x3x3_SFLOAT_BLOCK_EXT:
|
||||
return 1;
|
||||
case VK_FORMAT_ASTC_4x4x3_UNORM_BLOCK_EXT:
|
||||
return 1;
|
||||
case VK_FORMAT_ASTC_4x4x3_SRGB_BLOCK_EXT:
|
||||
return 1;
|
||||
case VK_FORMAT_ASTC_4x4x3_SFLOAT_BLOCK_EXT:
|
||||
return 1;
|
||||
case VK_FORMAT_ASTC_4x4x4_UNORM_BLOCK_EXT:
|
||||
return 1;
|
||||
case VK_FORMAT_ASTC_4x4x4_SRGB_BLOCK_EXT:
|
||||
return 1;
|
||||
case VK_FORMAT_ASTC_4x4x4_SFLOAT_BLOCK_EXT:
|
||||
return 1;
|
||||
case VK_FORMAT_ASTC_5x4x4_UNORM_BLOCK_EXT:
|
||||
return 1;
|
||||
case VK_FORMAT_ASTC_5x4x4_SRGB_BLOCK_EXT:
|
||||
return 1;
|
||||
case VK_FORMAT_ASTC_5x4x4_SFLOAT_BLOCK_EXT:
|
||||
return 1;
|
||||
case VK_FORMAT_ASTC_5x5x4_UNORM_BLOCK_EXT:
|
||||
return 1;
|
||||
case VK_FORMAT_ASTC_5x5x4_SRGB_BLOCK_EXT:
|
||||
return 1;
|
||||
case VK_FORMAT_ASTC_5x5x4_SFLOAT_BLOCK_EXT:
|
||||
return 1;
|
||||
case VK_FORMAT_ASTC_5x5x5_UNORM_BLOCK_EXT:
|
||||
return 1;
|
||||
case VK_FORMAT_ASTC_5x5x5_SRGB_BLOCK_EXT:
|
||||
return 1;
|
||||
case VK_FORMAT_ASTC_5x5x5_SFLOAT_BLOCK_EXT:
|
||||
return 1;
|
||||
case VK_FORMAT_ASTC_6x5x5_UNORM_BLOCK_EXT:
|
||||
return 1;
|
||||
case VK_FORMAT_ASTC_6x5x5_SRGB_BLOCK_EXT:
|
||||
return 1;
|
||||
case VK_FORMAT_ASTC_6x5x5_SFLOAT_BLOCK_EXT:
|
||||
return 1;
|
||||
case VK_FORMAT_ASTC_6x6x5_UNORM_BLOCK_EXT:
|
||||
return 1;
|
||||
case VK_FORMAT_ASTC_6x6x5_SRGB_BLOCK_EXT:
|
||||
return 1;
|
||||
case VK_FORMAT_ASTC_6x6x5_SFLOAT_BLOCK_EXT:
|
||||
return 1;
|
||||
case VK_FORMAT_ASTC_6x6x6_UNORM_BLOCK_EXT:
|
||||
return 1;
|
||||
case VK_FORMAT_ASTC_6x6x6_SRGB_BLOCK_EXT:
|
||||
return 1;
|
||||
case VK_FORMAT_ASTC_6x6x6_SFLOAT_BLOCK_EXT:
|
||||
return 1;
|
||||
case VK_FORMAT_R16G16_SFIXED5_NV:
|
||||
return 2;
|
||||
case VK_FORMAT_A1B5G5R5_UNORM_PACK16_KHR:
|
||||
return 2;
|
||||
case VK_FORMAT_A8_UNORM_KHR:
|
||||
return 1;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
// clang-format on
|
Reference in New Issue
Block a user