summaryrefslogtreecommitdiffstats
path: root/thirdparty/libktx/lib/dfdutils
diff options
context:
space:
mode:
authorRémi Verschelde <rverschelde@gmail.com>2024-04-05 10:44:32 +0200
committerRémi Verschelde <rverschelde@gmail.com>2024-04-05 12:18:00 +0200
commitd402f5ecf260f4ea7f16b913e8ab696a059b33c9 (patch)
treedee404526c22daba8c17eae9ecb4e4b12eaef1de /thirdparty/libktx/lib/dfdutils
parentf6a78f83aa4b74aa5cb80ca2e3419448b1998e4f (diff)
downloadredot-engine-d402f5ecf260f4ea7f16b913e8ab696a059b33c9.tar.gz
libktx: Update to 4.3.2
Diffstat (limited to 'thirdparty/libktx/lib/dfdutils')
-rw-r--r--thirdparty/libktx/lib/dfdutils/createdfd.c41
-rw-r--r--thirdparty/libktx/lib/dfdutils/dfd.h26
-rw-r--r--thirdparty/libktx/lib/dfdutils/dfd2vk.inl241
-rw-r--r--thirdparty/libktx/lib/dfdutils/interpretdfd.c113
-rw-r--r--thirdparty/libktx/lib/dfdutils/queries.c101
-rw-r--r--thirdparty/libktx/lib/dfdutils/vk2dfd.inl57
6 files changed, 370 insertions, 209 deletions
diff --git a/thirdparty/libktx/lib/dfdutils/createdfd.c b/thirdparty/libktx/lib/dfdutils/createdfd.c
index 2a5af00c7e..eb64204189 100644
--- a/thirdparty/libktx/lib/dfdutils/createdfd.c
+++ b/thirdparty/libktx/lib/dfdutils/createdfd.c
@@ -94,6 +94,10 @@ static uint32_t setChannelFlags(uint32_t channel, enum VkSuffix suffix)
channel |= KHR_DF_SAMPLE_DATATYPE_LINEAR;
}
break;
+ case s_S10_5:
+ channel |=
+ KHR_DF_SAMPLE_DATATYPE_SIGNED;
+ break;
}
return channel;
}
@@ -109,7 +113,6 @@ static void writeSample(uint32_t *DFD, int sampleNo, int channel,
float f;
} lower, upper;
uint32_t *sample = DFD + 1 + KHR_DF_WORD_SAMPLESTART + sampleNo * KHR_DF_WORD_SAMPLEWORDS;
- if (channel == 3) channel = KHR_DF_CHANNEL_RGBSDA_ALPHA;
if (channel == 3) channel = KHR_DF_CHANNEL_RGBSDA_ALPHA;
channel = setChannelFlags(channel, suffix);
@@ -159,6 +162,10 @@ static void writeSample(uint32_t *DFD, int sampleNo, int channel,
upper.f = 1.0f;
lower.f = 0.0f;
break;
+ case s_S10_5:
+ assert(bits == 16 && "Format with this suffix must be 16 bits per channel.");
+ upper.i = 32;
+ lower.i = ~upper.i + 1; // -32
}
sample[KHR_DF_SAMPLEWORD_SAMPLELOWER] = lower.i;
sample[KHR_DF_SAMPLEWORD_SAMPLEUPPER] = upper.i;
@@ -230,8 +237,9 @@ uint32_t *createDFDUnpacked(int bigEndian, int numChannels, int bytes,
* @param bits[] An array of length numChannels.
* Each entry is the number of bits composing the channel, in
* order starting at bit 0 of the packed type.
- * @param paddings[] An array of length numChannels.
- * Each entry is the number of padding bits after each channel.
+ * @param shiftBits[] An array of length numChannels.
+ * Each entry is the number of bits each channel is shifted
+ * and thus padded with insignificant bits.
* @param channels[] An array of length numChannels.
* Each entry enumerates the channel type: 0 = red, 1 = green,
* 2 = blue, 15 = alpha, in order starting at bit 0 of the
@@ -243,9 +251,9 @@ uint32_t *createDFDUnpacked(int bigEndian, int numChannels, int bytes,
* @return A data format descriptor in malloc'd data. The caller is responsible
* for freeing the descriptor.
**/
-uint32_t *createDFDPackedPadded(int bigEndian, int numChannels,
- int bits[], int paddings[], int channels[],
- enum VkSuffix suffix)
+uint32_t *createDFDPackedShifted(int bigEndian, int numChannels,
+ int bits[], int shiftBits[], int channels[],
+ enum VkSuffix suffix)
{
uint32_t *DFD = 0;
if (numChannels == 6) {
@@ -291,17 +299,18 @@ uint32_t *createDFDPackedPadded(int bigEndian, int numChannels,
int sampleCounter;
for (channelCounter = 0; channelCounter < numChannels; ++channelCounter) {
beChannelStart[channelCounter] = totalBits;
- totalBits += bits[channelCounter] + paddings[channelCounter];
+ totalBits += shiftBits[channelCounter] + bits[channelCounter];
}
BEMask = (totalBits - 1) & 0x18;
for (channelCounter = 0; channelCounter < numChannels; ++channelCounter) {
+ bitOffset += shiftBits[channelCounter];
bitChannel[bitOffset ^ BEMask] = channelCounter;
if (((bitOffset + bits[channelCounter] - 1) & ~7) != (bitOffset & ~7)) {
/* Continuation sample */
bitChannel[((bitOffset + bits[channelCounter] - 1) & ~7) ^ BEMask] = channelCounter;
numSamples++;
}
- bitOffset += bits[channelCounter] + paddings[channelCounter];
+ bitOffset += bits[channelCounter];
}
DFD = writeHeader(numSamples, totalBits >> 3, suffix, i_COLOR);
@@ -343,16 +352,17 @@ uint32_t *createDFDPackedPadded(int bigEndian, int numChannels,
int totalBits = 0;
int bitOffset = 0;
for (sampleCounter = 0; sampleCounter < numChannels; ++sampleCounter) {
- totalBits += bits[sampleCounter] + paddings[sampleCounter];
+ totalBits += shiftBits[sampleCounter] + bits[sampleCounter];
}
/* One sample per channel */
DFD = writeHeader(numChannels, totalBits >> 3, suffix, i_COLOR);
for (sampleCounter = 0; sampleCounter < numChannels; ++sampleCounter) {
+ bitOffset += shiftBits[sampleCounter];
writeSample(DFD, sampleCounter, channels[sampleCounter],
bits[sampleCounter], bitOffset,
1, 1, suffix);
- bitOffset += bits[sampleCounter] + paddings[sampleCounter];
+ bitOffset += bits[sampleCounter];
}
}
return DFD;
@@ -383,12 +393,12 @@ uint32_t *createDFDPacked(int bigEndian, int numChannels,
int bits[], int channels[],
enum VkSuffix suffix) {
assert(numChannels <= 6);
- int paddings[] = {0, 0, 0, 0, 0, 0};
- return createDFDPackedPadded(bigEndian, numChannels, bits, paddings, channels, suffix);
+ int shiftBits[] = {0, 0, 0, 0, 0, 0};
+ return createDFDPackedShifted(bigEndian, numChannels, bits, shiftBits, channels, suffix);
}
uint32_t *createDFD422(int bigEndian, int numSamples,
- int bits[], int paddings[], int channels[],
+ int bits[], int shiftBits[], int channels[],
int position_xs[], int position_ys[],
enum VkSuffix suffix) {
assert(!bigEndian); (void) bigEndian;
@@ -396,7 +406,7 @@ uint32_t *createDFD422(int bigEndian, int numSamples,
int totalBits = 0;
for (int i = 0; i < numSamples; ++i)
- totalBits += bits[i] + paddings[i];
+ totalBits += shiftBits[i] + bits[i];
assert(totalBits % 8 == 0);
uint32_t BDFDSize = sizeof(uint32_t) * (KHR_DF_WORD_SAMPLESTART + numSamples * KHR_DF_WORD_SAMPLEWORDS);
@@ -428,6 +438,7 @@ uint32_t *createDFD422(int bigEndian, int numSamples,
int bitOffset = 0;
for (int i = 0; i < numSamples; ++i) {
+ bitOffset += shiftBits[i];
KHR_DFDSETSVAL(BDFD, i, BITOFFSET, bitOffset);
KHR_DFDSETSVAL(BDFD, i, BITLENGTH, bits[i] - 1);
KHR_DFDSETSVAL(BDFD, i, CHANNELID, channels[i]);
@@ -438,7 +449,7 @@ uint32_t *createDFD422(int bigEndian, int numSamples,
KHR_DFDSETSVAL(BDFD, i, SAMPLEPOSITION3, 0);
KHR_DFDSETSVAL(BDFD, i, SAMPLELOWER, 0);
KHR_DFDSETSVAL(BDFD, i, SAMPLEUPPER, (1u << bits[i]) - 1u);
- bitOffset += bits[i] + paddings[i];
+ bitOffset += bits[i];
}
return DFD;
diff --git a/thirdparty/libktx/lib/dfdutils/dfd.h b/thirdparty/libktx/lib/dfdutils/dfd.h
index 7f1fb74a6b..756490fc82 100644
--- a/thirdparty/libktx/lib/dfdutils/dfd.h
+++ b/thirdparty/libktx/lib/dfdutils/dfd.h
@@ -35,7 +35,8 @@ enum VkSuffix {
s_SINT, /*!< Signed integer format. */
s_SFLOAT, /*!< Signed float format. */
s_UFLOAT, /*!< Unsigned float format. */
- s_SRGB /*!< sRGB normalized format. */
+ s_SRGB, /*!< sRGB normalized format. */
+ s_S10_5 /*!< 2's complement fixed-point; 5 fractional bits. */
};
/** Compression scheme, in Vulkan terms. */
@@ -68,15 +69,16 @@ typedef unsigned int uint32_t;
#endif
uint32_t* vk2dfd(enum VkFormat format);
+enum VkFormat dfd2vk(uint32_t* dfd);
/* Create a Data Format Descriptor for an unpacked format. */
uint32_t *createDFDUnpacked(int bigEndian, int numChannels, int bytes,
int redBlueSwap, enum VkSuffix suffix);
/* Create a Data Format Descriptor for a packed padded format. */
-uint32_t *createDFDPackedPadded(int bigEndian, int numChannels,
- int bits[], int paddings[], int channels[],
- enum VkSuffix suffix);
+uint32_t *createDFDPackedShifted(int bigEndian, int numChannels,
+ int bits[], int shiftBits[],
+ int channels[], enum VkSuffix suffix);
/* Create a Data Format Descriptor for a packed format. */
uint32_t *createDFDPacked(int bigEndian, int numChannels,
@@ -85,7 +87,7 @@ uint32_t *createDFDPacked(int bigEndian, int numChannels,
/* Create a Data Format Descriptor for a 4:2:2 format. */
uint32_t *createDFD422(int bigEndian, int numChannels,
- int bits[], int paddings[], int channels[],
+ int bits[], int shiftBits[], int channels[],
int position_xs[], int position_ys[],
enum VkSuffix suffix);
@@ -111,10 +113,11 @@ enum InterpretDFDResult {
i_SRGB_FORMAT_BIT = 1u << 2u, /*!< sRGB transfer function. */
i_NORMALIZED_FORMAT_BIT = 1u << 3u, /*!< Normalized (UNORM or SNORM). */
i_SIGNED_FORMAT_BIT = 1u << 4u, /*!< Format is signed. */
- i_FLOAT_FORMAT_BIT = 1u << 5u, /*!< Format is floating point. */
- i_COMPRESSED_FORMAT_BIT = 1u << 6u, /*!< Format is block compressed (422). */
- i_YUVSDA_FORMAT_BIT = 1u << 7u, /*!< Color model is YUVSDA. */
- i_UNSUPPORTED_ERROR_BIT = 1u << 8u, /*!< Format not successfully interpreted. */
+ i_FIXED_FORMAT_BIT = 1u << 5u, /*!< Format is a fixed-point representation. */
+ i_FLOAT_FORMAT_BIT = 1u << 6u, /*!< Format is floating point. */
+ i_COMPRESSED_FORMAT_BIT = 1u << 7u, /*!< Format is block compressed (422). */
+ i_YUVSDA_FORMAT_BIT = 1u << 8u, /*!< Color model is YUVSDA. */
+ i_UNSUPPORTED_ERROR_BIT = 1u << 9u, /*!< Format not successfully interpreted. */
/** "NONTRIVIAL_ENDIANNESS" means not big-endian, not little-endian
* (a channel has bits that are not consecutive in either order). **/
i_UNSUPPORTED_NONTRIVIAL_ENDIANNESS = i_UNSUPPORTED_ERROR_BIT,
@@ -198,9 +201,12 @@ getDFDComponentInfoUnpacked(const uint32_t* DFD, uint32_t* numComponents,
/* Return the number of components described by a DFD. */
uint32_t getDFDNumComponents(const uint32_t* DFD);
-/* Recreate and return the value of bytesPlane0 as it should be for the data
+/* Reconstruct and return the value of bytesPlane0 as it should be for the data
* post-inflation from variable-rate compression.
*/
+uint32_t
+reconstructDFDBytesPlane0FromSamples(const uint32_t* DFD);
+/* Deprecated. For backward compatibility. */
void
recreateBytesPlane0FromSampleInfo(const uint32_t* DFD, uint32_t* bytesPlane0);
diff --git a/thirdparty/libktx/lib/dfdutils/dfd2vk.inl b/thirdparty/libktx/lib/dfdutils/dfd2vk.inl
index 8b4de41597..a616566c74 100644
--- a/thirdparty/libktx/lib/dfdutils/dfd2vk.inl
+++ b/thirdparty/libktx/lib/dfdutils/dfd2vk.inl
@@ -4,12 +4,20 @@
/***************************** Do not edit. *****************************
Automatically generated by makedfd2vk.pl.
*************************************************************************/
-if (KHR_DFDVAL(dfd + 1, MODEL) == KHR_DF_MODEL_RGBSDA) {
+if (KHR_DFDVAL(dfd + 1, MODEL) == KHR_DF_MODEL_RGBSDA || KHR_DFDVAL(dfd + 1, MODEL) == KHR_DF_MODEL_YUVSDA) {
enum InterpretDFDResult r;
InterpretedDFDChannel R = {0,0};
InterpretedDFDChannel G = {0,0};
InterpretedDFDChannel B = {0,0};
InterpretedDFDChannel A = {0,0};
+ /* interpretDFD channel overloadings for YUVSDA formats. These are
+ * different from the mapping used by Vulkan. */
+ #define Y1 R
+ #define Y2 A
+ #define CB G
+ #define U G
+ #define CR B
+ #define V B
uint32_t wordBytes;
/* Special case exponent format */
@@ -44,8 +52,17 @@ if (KHR_DFDVAL(dfd + 1, MODEL) == KHR_DF_MODEL_RGBSDA) {
else if (wordBytes == 2) { /* PACK16 */
if (A.size == 4) {
if (R.offset == 12) return VK_FORMAT_R4G4B4A4_UNORM_PACK16;
- else return VK_FORMAT_B4G4R4A4_UNORM_PACK16;
- } else if (A.size == 0) { /* Three channels */
+ else if (B.offset == 12) return VK_FORMAT_B4G4R4A4_UNORM_PACK16;
+ else if (A.offset == 12) {
+ if (R.offset == 8) return VK_FORMAT_A4R4G4B4_UNORM_PACK16;
+ else return VK_FORMAT_A4B4G4R4_UNORM_PACK16;
+ }
+ } else if (G.size == 0 && B.size == 0 && A.size == 0) { /* One channel */
+ if (R.size == 10)
+ return VK_FORMAT_R10X6_UNORM_PACK16;
+ else if (R.size ==12)
+ return VK_FORMAT_R12X4_UNORM_PACK16;
+ } else if (A.size == 0) { /* Three channels */
if (B.offset == 0) return VK_FORMAT_R5G6B5_UNORM_PACK16;
else return VK_FORMAT_B5G6R5_UNORM_PACK16;
} else { /* Four channels, one-bit alpha */
@@ -54,7 +71,7 @@ if (KHR_DFDVAL(dfd + 1, MODEL) == KHR_DF_MODEL_RGBSDA) {
if (B.offset == 10) return VK_FORMAT_A1B5G5R5_UNORM_PACK16_KHR;
return VK_FORMAT_B5G5R5A1_UNORM_PACK16;
}
- } else if (wordBytes == 4) { /* PACK32 */
+ } else if (wordBytes == 4) { /* PACK32 or 2PACK16 */
if (A.size == 8) {
if ((r & i_SRGB_FORMAT_BIT)) return VK_FORMAT_A8B8G8R8_SRGB_PACK32;
if ((r & i_NORMALIZED_FORMAT_BIT) && !(r & i_SIGNED_FORMAT_BIT)) return VK_FORMAT_A8B8G8R8_UNORM_PACK32;
@@ -71,133 +88,171 @@ if (KHR_DFDVAL(dfd + 1, MODEL) == KHR_DF_MODEL_RGBSDA) {
if ((r & i_NORMALIZED_FORMAT_BIT) && (r & i_SIGNED_FORMAT_BIT)) return VK_FORMAT_A2B10G10R10_SNORM_PACK32;
if (!(r & i_NORMALIZED_FORMAT_BIT) && !(r & i_SIGNED_FORMAT_BIT)) return VK_FORMAT_A2B10G10R10_UINT_PACK32;
if (!(r & i_NORMALIZED_FORMAT_BIT) && (r & i_SIGNED_FORMAT_BIT)) return VK_FORMAT_A2B10G10R10_SINT_PACK32;
- } else if (R.size == 11) return VK_FORMAT_B10G11R11_UFLOAT_PACK32;
+ } else if (R.size == 11) {
+ return VK_FORMAT_B10G11R11_UFLOAT_PACK32;
+ } else if (R.size == 10 && G.size == 10 && B.size == 0) {
+ return VK_FORMAT_R10X6G10X6_UNORM_2PACK16;
+ } else if (R.size == 12 && G.size == 12 && B.size == 0) {
+ return VK_FORMAT_R12X4G12X4_UNORM_2PACK16;
+ }
+ } else if (wordBytes == 8) { /* 4PACK16 */
+ if (r & i_YUVSDA_FORMAT_BIT) {
+ /* In Vulkan G = Y, R = Cr, B = Cb. */
+ if (Y1.size == 10 && Y1.offset == 6 && Y2.size == 10 && Y2.offset == 38)
+ return VK_FORMAT_G10X6B10X6G10X6R10X6_422_UNORM_4PACK16;
+ if (Y1.size == 10 && Y1.offset == 22 && Y2.size == 10 && Y2.offset == 54)
+ return VK_FORMAT_B10X6G10X6R10X6G10X6_422_UNORM_4PACK16;
+ if (Y1.size == 12 && Y1.offset == 4 && Y2.size == 12 && Y2.offset == 36)
+ return VK_FORMAT_G12X4B12X4G12X4R12X4_422_UNORM_4PACK16;
+ if (Y1.size == 12 && Y1.offset == 20 && Y2.size == 12 && Y2.offset == 52)
+ return VK_FORMAT_B12X4G12X4R12X4G12X4_422_UNORM_4PACK16;
+ } else {
+ if (R.size == 10)
+ return VK_FORMAT_R10X6G10X6B10X6A10X6_UNORM_4PACK16;
+ else if (R.size == 12)
+ return VK_FORMAT_R12X4G12X4B12X4A12X4_UNORM_4PACK16;
+ }
}
} else { /* Not a packed format */
- if (wordBytes == 1) {
- if (A.size > 8 && R.size == 0 && G.size == 0 && B.size == 0 && (r & i_NORMALIZED_FORMAT_BIT) && !(r & i_SIGNED_FORMAT_BIT)) {
- return VK_FORMAT_A8_UNORM_KHR;
- }
- if (A.size > 0) { /* 4 channels */
- if (R.offset == 0) { /* RGBA */
- if ((r & i_SRGB_FORMAT_BIT)) return VK_FORMAT_R8G8B8A8_SRGB;
- if ((r & i_NORMALIZED_FORMAT_BIT) && !(r & i_SIGNED_FORMAT_BIT)) return VK_FORMAT_R8G8B8A8_UNORM;
- if ((r & i_NORMALIZED_FORMAT_BIT) && (r & i_SIGNED_FORMAT_BIT)) return VK_FORMAT_R8G8B8A8_SNORM;
- if (!(r & i_NORMALIZED_FORMAT_BIT) && !(r & i_SIGNED_FORMAT_BIT)) return VK_FORMAT_R8G8B8A8_UINT;
- if (!(r & i_NORMALIZED_FORMAT_BIT) && (r & i_SIGNED_FORMAT_BIT)) return VK_FORMAT_R8G8B8A8_SINT;
- } else { /* BGRA */
- if ((r & i_SRGB_FORMAT_BIT)) return VK_FORMAT_B8G8R8A8_SRGB;
- if ((r & i_NORMALIZED_FORMAT_BIT) && !(r & i_SIGNED_FORMAT_BIT)) return VK_FORMAT_B8G8R8A8_UNORM;
- if ((r & i_NORMALIZED_FORMAT_BIT) && (r & i_SIGNED_FORMAT_BIT)) return VK_FORMAT_B8G8R8A8_SNORM;
- if (!(r & i_NORMALIZED_FORMAT_BIT) && !(r & i_SIGNED_FORMAT_BIT)) return VK_FORMAT_B8G8R8A8_UINT;
- if (!(r & i_NORMALIZED_FORMAT_BIT) && (r & i_SIGNED_FORMAT_BIT)) return VK_FORMAT_B8G8R8A8_SINT;
- }
- } else if (B.size > 0) { /* 3 channels */
- if (R.offset == 0) { /* RGB */
- if ((r & i_SRGB_FORMAT_BIT)) return VK_FORMAT_R8G8B8_SRGB;
- if ((r & i_NORMALIZED_FORMAT_BIT) && !(r & i_SIGNED_FORMAT_BIT)) return VK_FORMAT_R8G8B8_UNORM;
- if ((r & i_NORMALIZED_FORMAT_BIT) && (r & i_SIGNED_FORMAT_BIT)) return VK_FORMAT_R8G8B8_SNORM;
- if (!(r & i_NORMALIZED_FORMAT_BIT) && !(r & i_SIGNED_FORMAT_BIT)) return VK_FORMAT_R8G8B8_UINT;
- if (!(r & i_NORMALIZED_FORMAT_BIT) && (r & i_SIGNED_FORMAT_BIT)) return VK_FORMAT_R8G8B8_SINT;
- } else { /* BGR */
- if ((r & i_SRGB_FORMAT_BIT)) return VK_FORMAT_B8G8R8_SRGB;
- if ((r & i_NORMALIZED_FORMAT_BIT) && !(r & i_SIGNED_FORMAT_BIT)) return VK_FORMAT_B8G8R8_UNORM;
- if ((r & i_NORMALIZED_FORMAT_BIT) && (r & i_SIGNED_FORMAT_BIT)) return VK_FORMAT_B8G8R8_SNORM;
- if (!(r & i_NORMALIZED_FORMAT_BIT) && !(r & i_SIGNED_FORMAT_BIT)) return VK_FORMAT_B8G8R8_UINT;
- if (!(r & i_NORMALIZED_FORMAT_BIT) && (r & i_SIGNED_FORMAT_BIT)) return VK_FORMAT_B8G8R8_SINT;
+ if (r & i_YUVSDA_FORMAT_BIT) {
+ /* In Vulkan G = Y, R = Cr, B = Cb. */
+ if (Y1.size == 1 && Y1.offset == 0 && Y2.size == 1 && Y2.offset == 2)
+ return VK_FORMAT_G8B8G8R8_422_UNORM;
+ else if (Y1.size == 1 && Y1.offset == 1 && Y2.size == 1 && Y2.offset == 3)
+ return VK_FORMAT_B8G8R8G8_422_UNORM;
+ else if (Y1.size == 2 && Y1.offset == 0 && Y2.size == 2 && Y2.offset == 4)
+ return VK_FORMAT_G16B16G16R16_422_UNORM;
+ else if (Y1.size == 2 && Y1.offset == 2 && Y2.size == 2 && Y2.offset == 6)
+ return VK_FORMAT_B16G16R16G16_422_UNORM;
+ else
+ return VK_FORMAT_UNDEFINED; // Until support added.
+ } else { /* Not YUV */
+ if (wordBytes == 1) {
+ if (A.size == 1 && R.size == 0 && G.size == 0 && B.size == 0 && (r & i_NORMALIZED_FORMAT_BIT) && !(r & i_SIGNED_FORMAT_BIT)) {
+ return VK_FORMAT_A8_UNORM_KHR;
}
- } else if (G.size > 0) { /* 2 channels */
+ if (A.size > 0) { /* 4 channels */
+ if (R.offset == 0) { /* RGBA */
+ if ((r & i_SRGB_FORMAT_BIT)) return VK_FORMAT_R8G8B8A8_SRGB;
+ if ((r & i_NORMALIZED_FORMAT_BIT) && !(r & i_SIGNED_FORMAT_BIT)) return VK_FORMAT_R8G8B8A8_UNORM;
+ if ((r & i_NORMALIZED_FORMAT_BIT) && (r & i_SIGNED_FORMAT_BIT)) return VK_FORMAT_R8G8B8A8_SNORM;
+ if (!(r & i_NORMALIZED_FORMAT_BIT) && !(r & i_SIGNED_FORMAT_BIT)) return VK_FORMAT_R8G8B8A8_UINT;
+ if (!(r & i_NORMALIZED_FORMAT_BIT) && (r & i_SIGNED_FORMAT_BIT)) return VK_FORMAT_R8G8B8A8_SINT;
+ } else { /* BGRA */
+ if ((r & i_SRGB_FORMAT_BIT)) return VK_FORMAT_B8G8R8A8_SRGB;
+ if ((r & i_NORMALIZED_FORMAT_BIT) && !(r & i_SIGNED_FORMAT_BIT)) return VK_FORMAT_B8G8R8A8_UNORM;
+ if ((r & i_NORMALIZED_FORMAT_BIT) && (r & i_SIGNED_FORMAT_BIT)) return VK_FORMAT_B8G8R8A8_SNORM;
+ if (!(r & i_NORMALIZED_FORMAT_BIT) && !(r & i_SIGNED_FORMAT_BIT)) return VK_FORMAT_B8G8R8A8_UINT;
+ if (!(r & i_NORMALIZED_FORMAT_BIT) && (r & i_SIGNED_FORMAT_BIT)) return VK_FORMAT_B8G8R8A8_SINT;
+ }
+ } else if (B.size > 0) { /* 3 channels */
+ if (R.offset == 0) { /* RGB */
+ if ((r & i_SRGB_FORMAT_BIT)) return VK_FORMAT_R8G8B8_SRGB;
+ if ((r & i_NORMALIZED_FORMAT_BIT) && !(r & i_SIGNED_FORMAT_BIT)) return VK_FORMAT_R8G8B8_UNORM;
+ if ((r & i_NORMALIZED_FORMAT_BIT) && (r & i_SIGNED_FORMAT_BIT)) return VK_FORMAT_R8G8B8_SNORM;
+ if (!(r & i_NORMALIZED_FORMAT_BIT) && !(r & i_SIGNED_FORMAT_BIT)) return VK_FORMAT_R8G8B8_UINT;
+ if (!(r & i_NORMALIZED_FORMAT_BIT) && (r & i_SIGNED_FORMAT_BIT)) return VK_FORMAT_R8G8B8_SINT;
+ } else { /* BGR */
+ if ((r & i_SRGB_FORMAT_BIT)) return VK_FORMAT_B8G8R8_SRGB;
+ if ((r & i_NORMALIZED_FORMAT_BIT) && !(r & i_SIGNED_FORMAT_BIT)) return VK_FORMAT_B8G8R8_UNORM;
+ if ((r & i_NORMALIZED_FORMAT_BIT) && (r & i_SIGNED_FORMAT_BIT)) return VK_FORMAT_B8G8R8_SNORM;
+ if (!(r & i_NORMALIZED_FORMAT_BIT) && !(r & i_SIGNED_FORMAT_BIT)) return VK_FORMAT_B8G8R8_UINT;
+ if (!(r & i_NORMALIZED_FORMAT_BIT) && (r & i_SIGNED_FORMAT_BIT)) return VK_FORMAT_B8G8R8_SINT;
+ }
+ } else if (G.size > 0) { /* 2 channels */
if ((r & i_SRGB_FORMAT_BIT)) return VK_FORMAT_R8G8_SRGB;
if ((r & i_NORMALIZED_FORMAT_BIT) && !(r & i_SIGNED_FORMAT_BIT)) return VK_FORMAT_R8G8_UNORM;
if ((r & i_NORMALIZED_FORMAT_BIT) && (r & i_SIGNED_FORMAT_BIT)) return VK_FORMAT_R8G8_SNORM;
if (!(r & i_NORMALIZED_FORMAT_BIT) && !(r & i_SIGNED_FORMAT_BIT)) return VK_FORMAT_R8G8_UINT;
if (!(r & i_NORMALIZED_FORMAT_BIT) && (r & i_SIGNED_FORMAT_BIT)) return VK_FORMAT_R8G8_SINT;
- } else { /* 1 channel */
+ } else { /* 1 channel */
if ((r & i_SRGB_FORMAT_BIT)) return VK_FORMAT_R8_SRGB;
if ((r & i_NORMALIZED_FORMAT_BIT) && !(r & i_SIGNED_FORMAT_BIT)) return VK_FORMAT_R8_UNORM;
if ((r & i_NORMALIZED_FORMAT_BIT) && (r & i_SIGNED_FORMAT_BIT)) return VK_FORMAT_R8_SNORM;
if (!(r & i_NORMALIZED_FORMAT_BIT) && !(r & i_SIGNED_FORMAT_BIT)) return VK_FORMAT_R8_UINT;
if (!(r & i_NORMALIZED_FORMAT_BIT) && (r & i_SIGNED_FORMAT_BIT)) return VK_FORMAT_R8_SINT;
- }
- } else if (wordBytes == 2) {
- if (A.size > 0) { /* 4 channels */
- if (R.offset == 0) { /* RGBA */
- if ((r & i_FLOAT_FORMAT_BIT)) return VK_FORMAT_R16G16B16A16_SFLOAT;
- if ((r & i_NORMALIZED_FORMAT_BIT) && !(r & i_SIGNED_FORMAT_BIT)) return VK_FORMAT_R16G16B16A16_UNORM;
- if ((r & i_NORMALIZED_FORMAT_BIT) && (r & i_SIGNED_FORMAT_BIT)) return VK_FORMAT_R16G16B16A16_SNORM;
- if (!(r & i_NORMALIZED_FORMAT_BIT) && !(r & i_SIGNED_FORMAT_BIT)) return VK_FORMAT_R16G16B16A16_UINT;
- if (!(r & i_NORMALIZED_FORMAT_BIT) && (r & i_SIGNED_FORMAT_BIT)) return VK_FORMAT_R16G16B16A16_SINT;
- } else { /* BGRA */
}
- } else if (B.size > 0) { /* 3 channels */
- if (R.offset == 0) { /* RGB */
- if ((r & i_FLOAT_FORMAT_BIT)) return VK_FORMAT_R16G16B16_SFLOAT;
- if ((r & i_NORMALIZED_FORMAT_BIT) && !(r & i_SIGNED_FORMAT_BIT)) return VK_FORMAT_R16G16B16_UNORM;
- if ((r & i_NORMALIZED_FORMAT_BIT) && (r & i_SIGNED_FORMAT_BIT)) return VK_FORMAT_R16G16B16_SNORM;
- if (!(r & i_NORMALIZED_FORMAT_BIT) && !(r & i_SIGNED_FORMAT_BIT)) return VK_FORMAT_R16G16B16_UINT;
- if (!(r & i_NORMALIZED_FORMAT_BIT) && (r & i_SIGNED_FORMAT_BIT)) return VK_FORMAT_R16G16B16_SINT;
- } else { /* BGR */
- }
- } else if (G.size > 0) { /* 2 channels */
+ } else if (wordBytes == 2) {
+ if ((r & i_FIXED_FORMAT_BIT) && R.size == 2 && G.size == 2) return VK_FORMAT_R16G16_S10_5_NV;
+ if (A.size > 0) { /* 4 channels */
+ if (R.offset == 0) { /* RGBA */
+ if ((r & i_FLOAT_FORMAT_BIT)) return VK_FORMAT_R16G16B16A16_SFLOAT;
+ if ((r & i_NORMALIZED_FORMAT_BIT) && !(r & i_SIGNED_FORMAT_BIT)) return VK_FORMAT_R16G16B16A16_UNORM;
+ if ((r & i_NORMALIZED_FORMAT_BIT) && (r & i_SIGNED_FORMAT_BIT)) return VK_FORMAT_R16G16B16A16_SNORM;
+ if (!(r & i_NORMALIZED_FORMAT_BIT) && !(r & i_SIGNED_FORMAT_BIT)) return VK_FORMAT_R16G16B16A16_UINT;
+ if (!(r & i_NORMALIZED_FORMAT_BIT) && (r & i_SIGNED_FORMAT_BIT)) return VK_FORMAT_R16G16B16A16_SINT;
+ } else { /* BGRA */
+ }
+ } else if (B.size > 0) { /* 3 channels */
+ if (R.offset == 0) { /* RGB */
+ if ((r & i_FLOAT_FORMAT_BIT)) return VK_FORMAT_R16G16B16_SFLOAT;
+ if ((r & i_NORMALIZED_FORMAT_BIT) && !(r & i_SIGNED_FORMAT_BIT)) return VK_FORMAT_R16G16B16_UNORM;
+ if ((r & i_NORMALIZED_FORMAT_BIT) && (r & i_SIGNED_FORMAT_BIT)) return VK_FORMAT_R16G16B16_SNORM;
+ if (!(r & i_NORMALIZED_FORMAT_BIT) && !(r & i_SIGNED_FORMAT_BIT)) return VK_FORMAT_R16G16B16_UINT;
+ if (!(r & i_NORMALIZED_FORMAT_BIT) && (r & i_SIGNED_FORMAT_BIT)) return VK_FORMAT_R16G16B16_SINT;
+ } else { /* BGR */
+ }
+ } else if (G.size > 0) { /* 2 channels */
if ((r & i_FLOAT_FORMAT_BIT)) return VK_FORMAT_R16G16_SFLOAT;
if ((r & i_NORMALIZED_FORMAT_BIT) && !(r & i_SIGNED_FORMAT_BIT)) return VK_FORMAT_R16G16_UNORM;
if ((r & i_NORMALIZED_FORMAT_BIT) && (r & i_SIGNED_FORMAT_BIT)) return VK_FORMAT_R16G16_SNORM;
if (!(r & i_NORMALIZED_FORMAT_BIT) && !(r & i_SIGNED_FORMAT_BIT)) return VK_FORMAT_R16G16_UINT;
if (!(r & i_NORMALIZED_FORMAT_BIT) && (r & i_SIGNED_FORMAT_BIT)) return VK_FORMAT_R16G16_SINT;
- } else { /* 1 channel */
+ } else { /* 1 channel */
if ((r & i_FLOAT_FORMAT_BIT)) return VK_FORMAT_R16_SFLOAT;
if ((r & i_NORMALIZED_FORMAT_BIT) && !(r & i_SIGNED_FORMAT_BIT)) return VK_FORMAT_R16_UNORM;
if ((r & i_NORMALIZED_FORMAT_BIT) && (r & i_SIGNED_FORMAT_BIT)) return VK_FORMAT_R16_SNORM;
if (!(r & i_NORMALIZED_FORMAT_BIT) && !(r & i_SIGNED_FORMAT_BIT)) return VK_FORMAT_R16_UINT;
if (!(r & i_NORMALIZED_FORMAT_BIT) && (r & i_SIGNED_FORMAT_BIT)) return VK_FORMAT_R16_SINT;
- }
- } else if (wordBytes == 4) {
- if (A.size > 0) { /* 4 channels */
- if (R.offset == 0) { /* RGBA */
- if ((r & i_FLOAT_FORMAT_BIT)) return VK_FORMAT_R32G32B32A32_SFLOAT;
- if (!(r & i_NORMALIZED_FORMAT_BIT) && !(r & i_SIGNED_FORMAT_BIT)) return VK_FORMAT_R32G32B32A32_UINT;
- if (!(r & i_NORMALIZED_FORMAT_BIT) && (r & i_SIGNED_FORMAT_BIT)) return VK_FORMAT_R32G32B32A32_SINT;
- } else { /* BGRA */
- }
- } else if (B.size > 0) { /* 3 channels */
- if (R.offset == 0) { /* RGB */
- if ((r & i_FLOAT_FORMAT_BIT)) return VK_FORMAT_R32G32B32_SFLOAT;
- if (!(r & i_NORMALIZED_FORMAT_BIT) && !(r & i_SIGNED_FORMAT_BIT)) return VK_FORMAT_R32G32B32_UINT;
- if (!(r & i_NORMALIZED_FORMAT_BIT) && (r & i_SIGNED_FORMAT_BIT)) return VK_FORMAT_R32G32B32_SINT;
- } else { /* BGR */
}
- } else if (G.size > 0) { /* 2 channels */
+ } else if (wordBytes == 4) {
+ if (A.size > 0) { /* 4 channels */
+ if (R.offset == 0) { /* RGBA */
+ if ((r & i_FLOAT_FORMAT_BIT)) return VK_FORMAT_R32G32B32A32_SFLOAT;
+ if (!(r & i_NORMALIZED_FORMAT_BIT) && !(r & i_SIGNED_FORMAT_BIT)) return VK_FORMAT_R32G32B32A32_UINT;
+ if (!(r & i_NORMALIZED_FORMAT_BIT) && (r & i_SIGNED_FORMAT_BIT)) return VK_FORMAT_R32G32B32A32_SINT;
+ } else { /* BGRA */
+ }
+ } else if (B.size > 0) { /* 3 channels */
+ if (R.offset == 0) { /* RGB */
+ if ((r & i_FLOAT_FORMAT_BIT)) return VK_FORMAT_R32G32B32_SFLOAT;
+ if (!(r & i_NORMALIZED_FORMAT_BIT) && !(r & i_SIGNED_FORMAT_BIT)) return VK_FORMAT_R32G32B32_UINT;
+ if (!(r & i_NORMALIZED_FORMAT_BIT) && (r & i_SIGNED_FORMAT_BIT)) return VK_FORMAT_R32G32B32_SINT;
+ } else { /* BGR */
+ }
+ } else if (G.size > 0) { /* 2 channels */
if ((r & i_FLOAT_FORMAT_BIT)) return VK_FORMAT_R32G32_SFLOAT;
if (!(r & i_NORMALIZED_FORMAT_BIT) && !(r & i_SIGNED_FORMAT_BIT)) return VK_FORMAT_R32G32_UINT;
if (!(r & i_NORMALIZED_FORMAT_BIT) && (r & i_SIGNED_FORMAT_BIT)) return VK_FORMAT_R32G32_SINT;
- } else { /* 1 channel */
+ } else { /* 1 channel */
if ((r & i_FLOAT_FORMAT_BIT)) return VK_FORMAT_R32_SFLOAT;
if (!(r & i_NORMALIZED_FORMAT_BIT) && !(r & i_SIGNED_FORMAT_BIT)) return VK_FORMAT_R32_UINT;
if (!(r & i_NORMALIZED_FORMAT_BIT) && (r & i_SIGNED_FORMAT_BIT)) return VK_FORMAT_R32_SINT;
- }
- } else if (wordBytes == 8) {
- if (A.size > 0) { /* 4 channels */
- if (R.offset == 0) { /* RGBA */
- if ((r & i_FLOAT_FORMAT_BIT)) return VK_FORMAT_R64G64B64A64_SFLOAT;
- if (!(r & i_NORMALIZED_FORMAT_BIT) && !(r & i_SIGNED_FORMAT_BIT)) return VK_FORMAT_R64G64B64A64_UINT;
- if (!(r & i_NORMALIZED_FORMAT_BIT) && (r & i_SIGNED_FORMAT_BIT)) return VK_FORMAT_R64G64B64A64_SINT;
- } else { /* BGRA */
- }
- } else if (B.size > 0) { /* 3 channels */
- if (R.offset == 0) { /* RGB */
- if ((r & i_FLOAT_FORMAT_BIT)) return VK_FORMAT_R64G64B64_SFLOAT;
- if (!(r & i_NORMALIZED_FORMAT_BIT) && !(r & i_SIGNED_FORMAT_BIT)) return VK_FORMAT_R64G64B64_UINT;
- if (!(r & i_NORMALIZED_FORMAT_BIT) && (r & i_SIGNED_FORMAT_BIT)) return VK_FORMAT_R64G64B64_SINT;
- } else { /* BGR */
}
- } else if (G.size > 0) { /* 2 channels */
+ } else if (wordBytes == 8) {
+ if (A.size > 0) { /* 4 channels */
+ if (R.offset == 0) { /* RGBA */
+ if ((r & i_FLOAT_FORMAT_BIT)) return VK_FORMAT_R64G64B64A64_SFLOAT;
+ if (!(r & i_NORMALIZED_FORMAT_BIT) && !(r & i_SIGNED_FORMAT_BIT)) return VK_FORMAT_R64G64B64A64_UINT;
+ if (!(r & i_NORMALIZED_FORMAT_BIT) && (r & i_SIGNED_FORMAT_BIT)) return VK_FORMAT_R64G64B64A64_SINT;
+ } else { /* BGRA */
+ }
+ } else if (B.size > 0) { /* 3 channels */
+ if (R.offset == 0) { /* RGB */
+ if ((r & i_FLOAT_FORMAT_BIT)) return VK_FORMAT_R64G64B64_SFLOAT;
+ if (!(r & i_NORMALIZED_FORMAT_BIT) && !(r & i_SIGNED_FORMAT_BIT)) return VK_FORMAT_R64G64B64_UINT;
+ if (!(r & i_NORMALIZED_FORMAT_BIT) && (r & i_SIGNED_FORMAT_BIT)) return VK_FORMAT_R64G64B64_SINT;
+ } else { /* BGR */
+ }
+ } else if (G.size > 0) { /* 2 channels */
if ((r & i_FLOAT_FORMAT_BIT)) return VK_FORMAT_R64G64_SFLOAT;
if (!(r & i_NORMALIZED_FORMAT_BIT) && !(r & i_SIGNED_FORMAT_BIT)) return VK_FORMAT_R64G64_UINT;
if (!(r & i_NORMALIZED_FORMAT_BIT) && (r & i_SIGNED_FORMAT_BIT)) return VK_FORMAT_R64G64_SINT;
- } else { /* 1 channel */
+ } else { /* 1 channel */
if ((r & i_FLOAT_FORMAT_BIT)) return VK_FORMAT_R64_SFLOAT;
if (!(r & i_NORMALIZED_FORMAT_BIT) && !(r & i_SIGNED_FORMAT_BIT)) return VK_FORMAT_R64_UINT;
if (!(r & i_NORMALIZED_FORMAT_BIT) && (r & i_SIGNED_FORMAT_BIT)) return VK_FORMAT_R64_SINT;
+ }
}
}
}
diff --git a/thirdparty/libktx/lib/dfdutils/interpretdfd.c b/thirdparty/libktx/lib/dfdutils/interpretdfd.c
index 6d25f33a1b..b58a79fb43 100644
--- a/thirdparty/libktx/lib/dfdutils/interpretdfd.c
+++ b/thirdparty/libktx/lib/dfdutils/interpretdfd.c
@@ -29,18 +29,37 @@ static uint32_t bit_ceil(uint32_t x) {
* @~English
* @brief Interpret a Data Format Descriptor for a simple format.
*
- * @param DFD Pointer to a Data Format Descriptor to interpret,
- described as 32-bit words in native endianness.
- Note that this is the whole descriptor, not just
- the basic descriptor block.
- * @param R Information about the decoded red channel or the depth channel, if any.
- * @param G Information about the decoded green channel or the stencil channel, if any.
- * @param B Information about the decoded blue channel, if any.
- * @param A Information about the decoded alpha channel, if any.
- * @param wordBytes Byte size of the channels (unpacked) or total size (packed).
+ * Handles "simple" cases that can be translated to things a GPU can access.
+ * For simplicity, it ignores the compressed formats, which are generally a
+ * single sample (and I believe are all defined to be little-endian in their
+ * in-memory layout, even if some documentation confuses this). Focuses on
+ * the layout and ignores sRGB except for reporting if that is the transfer
+ * function by way of a bit in the returned value.
+ *
+ * @param[in] DFD Pointer to a Data Format Descriptor to interpret,
+ * described as 32-bit words in native endianness.
+ * Note that this is the whole descriptor, not just
+ * the basic descriptor block.
+ * @param R[in,out] Pointer to struct to receive information about the decoded
+ * red channel, the Y channel, if YUV, or the depth channel,
+ * if any.
+ * @param G[in,out] Pointer to struct to receive information about the decoded
+ * green channel, the U (Cb) channel, if YUV, or the stencil
+ * channel, if any.
+ * @param B[in,out] Pointer to struct to receive information about the decoded
+ * blue channel, if any or the V (Cr) channel, if YUV.
+ * @param A[in,out] Pointer to struct to receive information about the decoded
+ * alpha channel, if any or the second Y channel, if YUV and
+ * any.
+ * @param wordBytes[in,out] Pointer to a uint32_t to receive the byte size of
+ * the channels (unpacked) or total size (packed).
*
* @return An enumerant describing the decoded value,
* or an error code in case of failure.
+ *
+ * The mapping of YUV channels to the parameter names used here is based on
+ * the channel ids in @c khr_df.h and is different from the convention used
+ * in format names in the Vulkan specification where G == Y, R = Cr and B = Cb.
**/
enum InterpretDFDResult interpretDFD(const uint32_t *DFD,
InterpretedDFDChannel *R,
@@ -49,14 +68,6 @@ enum InterpretDFDResult interpretDFD(const uint32_t *DFD,
InterpretedDFDChannel *A,
uint32_t *wordBytes)
{
- /* We specifically handle "simple" cases that can be translated */
- /* to things a GPU can access. For simplicity, we also ignore */
- /* the compressed formats, which are generally a single sample */
- /* (and I believe are all defined to be little-endian in their */
- /* in-memory layout, even if some documentation confuses this). */
- /* We also just worry about layout and ignore sRGB, since that's */
- /* trivial to extract anyway. */
-
/* DFD points to the whole descriptor, not the basic descriptor block. */
/* Make everything else relative to the basic descriptor block. */
const uint32_t *BDFDB = DFD+1;
@@ -78,7 +89,7 @@ enum InterpretDFDResult interpretDFD(const uint32_t *DFD,
/* First rule out the multiple planes case (trivially) */
/* - that is, we check that only bytesPlane0 is non-zero. */
- /* This means we don't handle YUV even if the API could. */
+ /* This means we don't handle multi-plane YUV, even if the API could. */
/* (We rely on KHR_DF_WORD_BYTESPLANE0..3 being the same and */
/* KHR_DF_WORD_BYTESPLANE4..7 being the same as a short cut.) */
if ((BDFDB[KHR_DF_WORD_BYTESPLANE0] & ~KHR_DF_MASK_BYTESPLANE0)
@@ -104,6 +115,8 @@ enum InterpretDFDResult interpretDFD(const uint32_t *DFD,
bool hasSigned = false;
bool hasFloat = false;
bool hasNormalized = false;
+ bool hasFixed = false;
+ khr_df_model_e model = KHR_DFDVAL(BDFDB, MODEL);
// Note: We're ignoring 9995, which is weird and worth special-casing
// rather than trying to generalise to all float formats.
@@ -116,13 +129,23 @@ enum InterpretDFDResult interpretDFD(const uint32_t *DFD,
// (i.e. set to the maximum bit value, and check min value) on
// the assumption that we're looking at a format which *came* from
// an API we can support.
- const bool isNormalized = isFloat ?
- *(float*) (void*) &BDFDB[KHR_DF_WORD_SAMPLESTART +
+ bool isFixed;
+ bool isNormalized;
+ if (isFloat) {
+ isNormalized = *(float*) (void*) &BDFDB[KHR_DF_WORD_SAMPLESTART +
KHR_DF_WORD_SAMPLEWORDS * i +
- KHR_DF_SAMPLEWORD_SAMPLEUPPER] != 1.0f :
- KHR_DFDSVAL(BDFDB, i, SAMPLEUPPER) != 1U;
-
+ KHR_DF_SAMPLEWORD_SAMPLEUPPER] != 1.0f;
+ isFixed = false;
+ } else {
+ uint32_t sampleUpper = KHR_DFDSVAL(BDFDB, i, SAMPLEUPPER);
+ uint32_t maxVal = 1U << KHR_DFDSVAL(BDFDB, i, BITLENGTH);
+ if (!isSigned) maxVal <<= 1;
+ maxVal--;
+ isFixed = 1U < sampleUpper && sampleUpper < maxVal;
+ isNormalized = !isFixed && sampleUpper != 1U;
+ }
hasSigned |= isSigned;
+ hasFixed |= isFixed;
hasFloat |= isFloat;
// By our definition the normalizedness of a single bit channel (like in RGBA 5:5:5:1)
// is ambiguous. Ignore these during normalized checks.
@@ -132,9 +155,10 @@ enum InterpretDFDResult interpretDFD(const uint32_t *DFD,
result |= hasSigned ? i_SIGNED_FORMAT_BIT : 0;
result |= hasFloat ? i_FLOAT_FORMAT_BIT : 0;
result |= hasNormalized ? i_NORMALIZED_FORMAT_BIT : 0;
+ result |= hasFixed ? i_FIXED_FORMAT_BIT : 0;
// Checks based on color model
- if (KHR_DFDVAL(BDFDB, MODEL) == KHR_DF_MODEL_YUVSDA) {
+ if (model == KHR_DF_MODEL_YUVSDA) {
result |= i_NORMALIZED_FORMAT_BIT;
result |= i_COMPRESSED_FORMAT_BIT;
result |= i_YUVSDA_FORMAT_BIT;
@@ -165,7 +189,7 @@ enum InterpretDFDResult interpretDFD(const uint32_t *DFD,
*wordBytes = ((result & i_PACKED_FORMAT_BIT) ? 4 : 1) * bit_ceil(largestSampleSize) / 8;
} else if (KHR_DFDVAL(BDFDB, MODEL) == KHR_DF_MODEL_RGBSDA) {
- /* We only pay attention to sRGB. */
+ /* Check if transfer is sRGB. */
if (KHR_DFDVAL(BDFDB, TRANSFER) == KHR_DF_TRANSFER_SRGB) result |= i_SRGB_FORMAT_BIT;
/* We only support samples at coordinate 0,0,0,0. */
@@ -175,7 +199,11 @@ enum InterpretDFDResult interpretDFD(const uint32_t *DFD,
if (KHR_DFDSVAL(BDFDB, sampleCounter, SAMPLEPOSITION_ALL))
return i_UNSUPPORTED_MULTIPLE_SAMPLE_LOCATIONS;
}
+ }
+ if (model == KHR_DF_MODEL_RGBSDA || model == KHR_DF_MODEL_YUVSDA) {
+ /* The values of the DEPTH and STENCIL tokens are the same for */
+ /* RGBSDA and YUVSDA. */
/* For Depth/Stencil formats mixed channels are allowed */
for (uint32_t sampleCounter = 0; sampleCounter < numSamples; ++sampleCounter) {
switch (KHR_DFDSVAL(BDFDB, sampleCounter, CHANNELID)) {
@@ -206,6 +234,9 @@ enum InterpretDFDResult interpretDFD(const uint32_t *DFD,
}
}
+ /* This all relies on the channel id values for RGB being equal to */
+ /* those for YUV. */
+
/* Remember: the canonical ordering of samples is to start with */
/* the lowest bit of the channel/location which touches bit 0 of */
/* the data, when the latter is concatenated in little-endian order, */
@@ -288,8 +319,20 @@ enum InterpretDFDResult interpretDFD(const uint32_t *DFD,
currentByteOffset = sampleByteOffset;
currentBitLength = sampleBitLength;
if (sampleChannelPtr->size) {
- /* Uh-oh, we've seen this channel before. */
- return i_UNSUPPORTED_NONTRIVIAL_ENDIANNESS;
+ if (model == KHR_DF_MODEL_YUVSDA && sampleChannel == KHR_DF_CHANNEL_YUVSDA_Y) {
+ if (sampleChannelPtr == R) {
+ /* We've got another Y channel. Record details in A. */
+ if (A->size == 0) {
+ sampleChannelPtr = A;
+ } else {
+ /* Uh-oh, we've already got a second Y or an alpha channel. */
+ return i_UNSUPPORTED_CHANNEL_TYPES;
+ }
+ }
+ } else {
+ /* Uh-oh, we've seen this channel before. */
+ return i_UNSUPPORTED_NONTRIVIAL_ENDIANNESS;
+ }
}
/* For now, record the bit offset in little-endian terms, */
/* because we may not know to reverse it yet. */
@@ -378,8 +421,20 @@ enum InterpretDFDResult interpretDFD(const uint32_t *DFD,
currentByteOffset = sampleByteOffset;
currentByteLength = sampleByteLength;
if (sampleChannelPtr->size) {
- /* Uh-oh, we've seen this channel before. */
- return i_UNSUPPORTED_NONTRIVIAL_ENDIANNESS;
+ if (model == KHR_DF_MODEL_YUVSDA && sampleChannel == KHR_DF_CHANNEL_YUVSDA_Y) {
+ if (sampleChannelPtr == R) {
+ /* We've got another Y channel. Record details in A. */
+ if (A->size == 0) {
+ sampleChannelPtr = A;
+ } else {
+ /* Uh-oh, we've already got a second Y or an alpha channel. */
+ return i_UNSUPPORTED_CHANNEL_TYPES;
+ }
+ }
+ } else {
+ /* Uh-oh, we've seen this channel before. */
+ return i_UNSUPPORTED_NONTRIVIAL_ENDIANNESS;
+ }
}
/* For now, record the byte offset in little-endian terms, */
/* because we may not know to reverse it yet. */
diff --git a/thirdparty/libktx/lib/dfdutils/queries.c b/thirdparty/libktx/lib/dfdutils/queries.c
index 19488f9e33..66d77cf6ad 100644
--- a/thirdparty/libktx/lib/dfdutils/queries.c
+++ b/thirdparty/libktx/lib/dfdutils/queries.c
@@ -41,15 +41,15 @@ getDFDComponentInfoUnpacked(const uint32_t* DFD, uint32_t* numComponents,
{
const uint32_t *BDFDB = DFD+1;
uint32_t numSamples = KHR_DFDSAMPLECOUNT(BDFDB);
- uint32_t sampleCounter;
+ uint32_t sampleNumber;
uint32_t currentChannel = ~0U; /* Don't start matched. */
/* This is specifically for unpacked formats which means the size of */
/* each component is the same. */
*numComponents = 0;
- for (sampleCounter = 0; sampleCounter < numSamples; ++sampleCounter) {
- uint32_t sampleByteLength = (KHR_DFDSVAL(BDFDB, sampleCounter, BITLENGTH) + 1) >> 3U;
- uint32_t sampleChannel = KHR_DFDSVAL(BDFDB, sampleCounter, CHANNELID);
+ for (sampleNumber = 0; sampleNumber < numSamples; ++sampleNumber) {
+ uint32_t sampleByteLength = (KHR_DFDSVAL(BDFDB, sampleNumber, BITLENGTH) + 1) >> 3U;
+ uint32_t sampleChannel = KHR_DFDSVAL(BDFDB, sampleNumber, CHANNELID);
if (sampleChannel == currentChannel) {
/* Continuation of the same channel. */
@@ -85,10 +85,10 @@ uint32_t getDFDNumComponents(const uint32_t* DFD)
uint32_t currentChannel = ~0U; /* Don't start matched. */
uint32_t numComponents = 0;
uint32_t numSamples = KHR_DFDSAMPLECOUNT(BDFDB);
- uint32_t sampleCounter;
+ uint32_t sampleNumber;
- for (sampleCounter = 0; sampleCounter < numSamples; ++sampleCounter) {
- uint32_t sampleChannel = KHR_DFDSVAL(BDFDB, sampleCounter, CHANNELID);
+ for (sampleNumber = 0; sampleNumber < numSamples; ++sampleNumber) {
+ uint32_t sampleChannel = KHR_DFDSVAL(BDFDB, sampleNumber, CHANNELID);
if (sampleChannel != currentChannel) {
numComponents++;
currentChannel = sampleChannel;
@@ -97,50 +97,83 @@ uint32_t getDFDNumComponents(const uint32_t* DFD)
return numComponents;
}
+
/**
* @~English
- * @brief Recreate the value of bytesPlane0 from sample info.
+ * @brief Reconstruct the value of bytesPlane0 from sample info.
*
- * This can be use to recreate the value of bytesPlane0 for data that
- * has been variable-rate compressed so has bytesPlane0 = 0. For DFDs
- * that are valid for KTX files. Little-endian data only and no multi-plane
- * formats.
+ * Reconstruct the value for data that has been variable-rate compressed so
+ * has bytesPlane0 = 0. For DFDs that are valid for KTX files. Little-endian
+ * data only and no multi-plane formats.
*
* @param DFD Pointer to a Data Format Descriptor for which,
* described as 32-bit words in native endianness.
* Note that this is the whole descriptor, not just
* the basic descriptor block.
- * @param bytesPlane0 pointer to a 32-bit word in which the recreated
- * value of bytesPlane0 will be written.
*/
-void
-recreateBytesPlane0FromSampleInfo(const uint32_t* DFD, uint32_t* bytesPlane0)
+uint32_t
+reconstructDFDBytesPlane0FromSamples(const uint32_t* DFD)
{
const uint32_t *BDFDB = DFD+1;
uint32_t numSamples = KHR_DFDSAMPLECOUNT(BDFDB);
- uint32_t sampleCounter;
+ uint32_t sampleNumber;
uint32_t bitsPlane0 = 0;
- uint32_t* bitOffsets = malloc(sizeof(uint32_t) * numSamples);
- memset(bitOffsets, -1, sizeof(uint32_t) * numSamples);
- for (sampleCounter = 0; sampleCounter < numSamples; ++sampleCounter) {
- uint32_t sampleBitOffset = KHR_DFDSVAL(BDFDB, sampleCounter, BITOFFSET);
- /* The sample bitLength field stores the bit length - 1. */
- uint32_t sampleBitLength = KHR_DFDSVAL(BDFDB, sampleCounter, BITLENGTH) + 1;
- uint32_t i;
- for (i = 0; i < numSamples; i++) {
- if (sampleBitOffset == bitOffsets[i]) {
- // This sample is being repeated as in e.g. RGB9E5.
- break;
+ int32_t largestOffset = 0;
+ uint32_t sampleNumberWithLargestOffset = 0;
+
+ // Special case these depth{,-stencil} formats. The unused bits are
+ // in the MSBs so have no visibility in the DFD therefore the max offset
+ // algorithm below returns a value that is too small.
+ if (KHR_DFDSVAL(BDFDB, 0, CHANNELID) == KHR_DF_CHANNEL_COMMON_DEPTH) {
+ if (numSamples == 1) {
+ if (KHR_DFDSVAL(BDFDB, 0, BITLENGTH) + 1 == 24) {
+ // X8_D24_UNORM_PACK32,
+ return 4;
+ }
+ } else if (numSamples == 2) {
+ if (KHR_DFDSVAL(BDFDB, 0, BITLENGTH) + 1 == 16) {
+ // D16_UNORM_S8_UINT
+ return 4;
+ }
+ if (KHR_DFDSVAL(BDFDB, 0, BITLENGTH) + 1 == 32
+ && KHR_DFDSVAL(BDFDB, 1, CHANNELID) == KHR_DF_CHANNEL_COMMON_STENCIL) {
+ // D32_SFLOAT_S8_UINT
+ return 8;
}
}
- if (i == numSamples) {
- // Previously unseen bitOffset. Bump size.
- bitsPlane0 += sampleBitLength;
- bitOffsets[sampleCounter] = sampleBitOffset;
+ }
+ for (sampleNumber = 0; sampleNumber < numSamples; ++sampleNumber) {
+ int32_t sampleBitOffset = KHR_DFDSVAL(BDFDB, sampleNumber, BITOFFSET);
+ if (sampleBitOffset > largestOffset) {
+ largestOffset = sampleBitOffset;
+ sampleNumberWithLargestOffset = sampleNumber;
}
}
- free(bitOffsets);
- *bytesPlane0 = bitsPlane0 >> 3U;
+
+ /* The sample bitLength field stores the bit length - 1. */
+ uint32_t sampleBitLength = KHR_DFDSVAL(BDFDB, sampleNumberWithLargestOffset, BITLENGTH) + 1;
+ bitsPlane0 = largestOffset + sampleBitLength;
+ return bitsPlane0 >> 3U;
}
+/**
+ * @~English
+ * @brief Reconstruct the value of bytesPlane0 from sample info.
+ *
+ * @see reconstructDFDBytesPlane0FromSamples for details.
+ * @deprecated For backward comparibility only. Use
+ * reconstructDFDBytesPlane0FromSamples.
+ *
+ * @param DFD Pointer to a Data Format Descriptor for which,
+ * described as 32-bit words in native endianness.
+ * Note that this is the whole descriptor, not just
+ * the basic descriptor block.
+ * @param bytesPlane0 pointer to a 32-bit word in which the recreated
+ * value of bytesPlane0 will be written.
+ */
+void
+recreateBytesPlane0FromSampleInfo(const uint32_t* DFD, uint32_t* bytesPlane0)
+{
+ *bytesPlane0 = reconstructDFDBytesPlane0FromSamples(DFD);
+}
diff --git a/thirdparty/libktx/lib/dfdutils/vk2dfd.inl b/thirdparty/libktx/lib/dfdutils/vk2dfd.inl
index 25c7a2c238..3398441e8c 100644
--- a/thirdparty/libktx/lib/dfdutils/vk2dfd.inl
+++ b/thirdparty/libktx/lib/dfdutils/vk2dfd.inl
@@ -277,68 +277,68 @@ case VK_FORMAT_ASTC_12x10_SRGB_BLOCK: return createDFDCompressed(c_ASTC, 12, 10,
case VK_FORMAT_ASTC_12x12_UNORM_BLOCK: return createDFDCompressed(c_ASTC, 12, 12, 1, s_UNORM);
case VK_FORMAT_ASTC_12x12_SRGB_BLOCK: return createDFDCompressed(c_ASTC, 12, 12, 1, s_SRGB);
case VK_FORMAT_G8B8G8R8_422_UNORM: {
- int channels[] = {0, 1, 0, 2}; int bits[] = {8, 8, 8, 8}; int paddings[] = {0, 0, 0, 0};
+ int channels[] = {0, 1, 0, 2}; int bits[] = {8, 8, 8, 8}; int shiftBits[] = {0, 0, 0, 0};
int position_xs[] = {64, 64, 192, 64}; int position_ys[] = {128, 128, 128, 128};
- return createDFD422(0, 4, bits, paddings, channels, position_xs, position_ys, s_UNORM);
+ return createDFD422(0, 4, bits, shiftBits, channels, position_xs, position_ys, s_UNORM);
}
case VK_FORMAT_B8G8R8G8_422_UNORM: {
- int channels[] = {1, 0, 2, 0}; int bits[] = {8, 8, 8, 8}; int paddings[] = {0, 0, 0, 0};
+ int channels[] = {1, 0, 2, 0}; int bits[] = {8, 8, 8, 8}; int shiftBits[] = {0, 0, 0, 0};
int position_xs[] = {64, 64, 64, 192}; int position_ys[] = {128, 128, 128, 128};
- return createDFD422(0, 4, bits, paddings, channels, position_xs, position_ys, s_UNORM);
+ return createDFD422(0, 4, bits, shiftBits, channels, position_xs, position_ys, s_UNORM);
}
case VK_FORMAT_R10X6_UNORM_PACK16: {
- int channels[] = {0}; int bits[] = {10}; int paddings[] = {6};
- return createDFDPackedPadded(0, 1, bits, paddings, channels, s_UNORM);
+ int channels[] = {0}; int bits[] = {10}; int shiftBits[] = {6};
+ return createDFDPackedShifted(0, 1, bits, shiftBits, channels, s_UNORM);
}
case VK_FORMAT_R10X6G10X6_UNORM_2PACK16: {
- int channels[] = {0, 1}; int bits[] = {10, 10}; int paddings[] = {6, 6};
- return createDFDPackedPadded(0, 2, bits, paddings, channels, s_UNORM);
+ int channels[] = {0, 1}; int bits[] = {10, 10}; int shiftBits[] = {6, 6};
+ return createDFDPackedShifted(0, 2, bits, shiftBits, channels, s_UNORM);
}
case VK_FORMAT_R10X6G10X6B10X6A10X6_UNORM_4PACK16: {
- int channels[] = {0, 1, 2, 3}; int bits[] = {10, 10, 10, 10}; int paddings[] = {6, 6, 6, 6};
- return createDFDPackedPadded(0, 4, bits, paddings, channels, s_UNORM);
+ int channels[] = {0, 1, 2, 3}; int bits[] = {10, 10, 10, 10}; int shiftBits[] = {6, 6, 6, 6};
+ return createDFDPackedShifted(0, 4, bits, shiftBits, channels, s_UNORM);
}
case VK_FORMAT_G10X6B10X6G10X6R10X6_422_UNORM_4PACK16: {
- int channels[] = {0, 1, 0, 2}; int bits[] = {10, 10, 10, 10}; int paddings[] = {6, 6, 6, 6};
+ int channels[] = {0, 1, 0, 2}; int bits[] = {10, 10, 10, 10}; int shiftBits[] = {6, 6, 6, 6};
int position_xs[] = {64, 64, 192, 64}; int position_ys[] = {128, 128, 128, 128};
- return createDFD422(0, 4, bits, paddings, channels, position_xs, position_ys, s_UNORM);
+ return createDFD422(0, 4, bits, shiftBits, channels, position_xs, position_ys, s_UNORM);
}
case VK_FORMAT_B10X6G10X6R10X6G10X6_422_UNORM_4PACK16: {
- int channels[] = {1, 0, 2, 0}; int bits[] = {10, 10, 10, 10}; int paddings[] = {6, 6, 6, 6};
+ int channels[] = {1, 0, 2, 0}; int bits[] = {10, 10, 10, 10}; int shiftBits[] = {6, 6, 6, 6};
int position_xs[] = {64, 64, 64, 192}; int position_ys[] = {128, 128, 128, 128};
- return createDFD422(0, 4, bits, paddings, channels, position_xs, position_ys, s_UNORM);
+ return createDFD422(0, 4, bits, shiftBits, channels, position_xs, position_ys, s_UNORM);
}
case VK_FORMAT_R12X4_UNORM_PACK16: {
- int channels[] = {0}; int bits[] = {12}; int paddings[] = {4};
- return createDFDPackedPadded(0, 1, bits, paddings, channels, s_UNORM);
+ int channels[] = {0}; int bits[] = {12}; int shiftBits[] = {4};
+ return createDFDPackedShifted(0, 1, bits, shiftBits, channels, s_UNORM);
}
case VK_FORMAT_R12X4G12X4_UNORM_2PACK16: {
- int channels[] = {0, 1}; int bits[] = {12, 12}; int paddings[] = {4, 4};
- return createDFDPackedPadded(0, 2, bits, paddings, channels, s_UNORM);
+ int channels[] = {0, 1}; int bits[] = {12, 12}; int shiftBits[] = {4, 4};
+ return createDFDPackedShifted(0, 2, bits, shiftBits, channels, s_UNORM);
}
case VK_FORMAT_R12X4G12X4B12X4A12X4_UNORM_4PACK16: {
- int channels[] = {0, 1, 2, 3}; int bits[] = {12, 12, 12, 12}; int paddings[] = {4, 4, 4, 4};
- return createDFDPackedPadded(0, 4, bits, paddings, channels, s_UNORM);
+ int channels[] = {0, 1, 2, 3}; int bits[] = {12, 12, 12, 12}; int shiftBits[] = {4, 4, 4, 4};
+ return createDFDPackedShifted(0, 4, bits, shiftBits, channels, s_UNORM);
}
case VK_FORMAT_G12X4B12X4G12X4R12X4_422_UNORM_4PACK16: {
- int channels[] = {0, 1, 0, 2}; int bits[] = {12, 12, 12, 12}; int paddings[] = {4, 4, 4, 4};
+ int channels[] = {0, 1, 0, 2}; int bits[] = {12, 12, 12, 12}; int shiftBits[] = {4, 4, 4, 4};
int position_xs[] = {64, 64, 192, 64}; int position_ys[] = {128, 128, 128, 128};
- return createDFD422(0, 4, bits, paddings, channels, position_xs, position_ys, s_UNORM);
+ return createDFD422(0, 4, bits, shiftBits, channels, position_xs, position_ys, s_UNORM);
}
case VK_FORMAT_B12X4G12X4R12X4G12X4_422_UNORM_4PACK16: {
- int channels[] = {1, 0, 2, 0}; int bits[] = {12, 12, 12, 12}; int paddings[] = {4, 4, 4, 4};
+ int channels[] = {1, 0, 2, 0}; int bits[] = {12, 12, 12, 12}; int shiftBits[] = {4, 4, 4, 4};
int position_xs[] = {64, 64, 64, 192}; int position_ys[] = {128, 128, 128, 128};
- return createDFD422(0, 4, bits, paddings, channels, position_xs, position_ys, s_UNORM);
+ return createDFD422(0, 4, bits, shiftBits, channels, position_xs, position_ys, s_UNORM);
}
case VK_FORMAT_G16B16G16R16_422_UNORM: {
- int channels[] = {0, 1, 0, 2}; int bits[] = {16, 16, 16, 16}; int paddings[] = {0, 0, 0, 0};
+ int channels[] = {0, 1, 0, 2}; int bits[] = {16, 16, 16, 16}; int shiftBits[] = {0, 0, 0, 0};
int position_xs[] = {64, 64, 192, 64}; int position_ys[] = {128, 128, 128, 128};
- return createDFD422(0, 4, bits, paddings, channels, position_xs, position_ys, s_UNORM);
+ return createDFD422(0, 4, bits, shiftBits, channels, position_xs, position_ys, s_UNORM);
}
case VK_FORMAT_B16G16R16G16_422_UNORM: {
- int channels[] = {1, 0, 2, 0}; int bits[] = {16, 16, 16, 16}; int paddings[] = {0, 0, 0, 0};
+ int channels[] = {1, 0, 2, 0}; int bits[] = {16, 16, 16, 16}; int shiftBits[] = {0, 0, 0, 0};
int position_xs[] = {64, 64, 64, 192}; int position_ys[] = {128, 128, 128, 128};
- return createDFD422(0, 4, bits, paddings, channels, position_xs, position_ys, s_UNORM);
+ return createDFD422(0, 4, bits, shiftBits, channels, position_xs, position_ys, s_UNORM);
}
case VK_FORMAT_A4R4G4B4_UNORM_PACK16: {
int channels[] = {2,1,0,3}; int bits[] = {4,4,4,4};
@@ -402,6 +402,7 @@ case VK_FORMAT_ASTC_6x6x6_UNORM_BLOCK_EXT: return createDFDCompressed(c_ASTC, 6,
case VK_FORMAT_ASTC_6x6x6_SRGB_BLOCK_EXT: return createDFDCompressed(c_ASTC, 6, 6, 6, s_SRGB);
case VK_FORMAT_ASTC_6x6x6_SFLOAT_BLOCK_EXT: return createDFDCompressed(c_ASTC, 6, 6, 6, s_SFLOAT);
#endif
+case VK_FORMAT_R16G16_S10_5_NV: return createDFDUnpacked(0, 2, 2, 0, s_S10_5);
case VK_FORMAT_A1B5G5R5_UNORM_PACK16_KHR: {
int channels[] = {0,1,2,3}; int bits[] = {5,5,5,1};
return createDFDPacked(0, 4, bits, channels, s_UNORM);