diff options
author | Rémi Verschelde <rverschelde@gmail.com> | 2024-04-05 10:44:32 +0200 |
---|---|---|
committer | Rémi Verschelde <rverschelde@gmail.com> | 2024-04-05 12:18:00 +0200 |
commit | d402f5ecf260f4ea7f16b913e8ab696a059b33c9 (patch) | |
tree | dee404526c22daba8c17eae9ecb4e4b12eaef1de /thirdparty/libktx/lib/dfdutils | |
parent | f6a78f83aa4b74aa5cb80ca2e3419448b1998e4f (diff) | |
download | redot-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.c | 41 | ||||
-rw-r--r-- | thirdparty/libktx/lib/dfdutils/dfd.h | 26 | ||||
-rw-r--r-- | thirdparty/libktx/lib/dfdutils/dfd2vk.inl | 241 | ||||
-rw-r--r-- | thirdparty/libktx/lib/dfdutils/interpretdfd.c | 113 | ||||
-rw-r--r-- | thirdparty/libktx/lib/dfdutils/queries.c | 101 | ||||
-rw-r--r-- | thirdparty/libktx/lib/dfdutils/vk2dfd.inl | 57 |
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); |