Skip to content

Commit

Permalink
Implement the extended scope and further improvements for ktxtools (K…
Browse files Browse the repository at this point in the history
…hronosGroup#722)

- tools: Implement stdout support
- tools: Implement stdin support
- tools: Implement 4:2:2 support
- tools: Implement support for 10X6 and 10X4 formats
- tools: Implement support for B10G11R11_UFLOAT and E5B9G9R9_UFLOAT formats
- tools: Complete support for Depth-Stencil formats
- tools: Improvements, cleanup and bug fixes
- extract: Implement fragment URI support
- extract: Implement 4:2:2 sub-sampling
- validate: Fix and extend padding byte validation checks
- cts: Add support for stdin/stdout test cases (including binary IO)
- cts: Add tests to cover new features and capabilities
- cts: Extend existing tests to improve coverage
- cts: Test runner now deletes matching output files (this enables easy packaging of mismatching files)
- cts: Added a new cli arg to the runner script: --keep-matching-outputs to prevent the deletion of matching output files
- dfdUtils: Implement 4:2:2 support
- dfdUtils: Implement support for 10X6 and 10X4 formats
- imageio: Fix stdin support
- ktx: Add stringToVkFormat to mkvkformatfiles
- ktx: Implement 3D BC support (ASTC 3D Blocks)
- ktx: Implement 4:2:2 support
- ktx: Complete support for Depth-Stencil formats
- ktx: Improve interpretDFD
- ktx: Improvements, cleanup and bug fixes
- cmake: Add CMake generator expression for output directory on Mac
  • Loading branch information
Császár Mátyás authored Jul 1, 2023
1 parent 3aed712 commit dbd9ff0
Show file tree
Hide file tree
Showing 14 changed files with 1,313 additions and 295 deletions.
104 changes: 97 additions & 7 deletions lib/dfdutils/createdfd.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,9 @@
* Author: Andrew Garrard
*/

#include <assert.h>
#include <stdlib.h>
#include <string.h>
#include <KHR/khr_df.h>

#include "dfd.h"
Expand Down Expand Up @@ -228,6 +230,8 @@ uint32_t *createDFDUnpacked(int bigEndian, int numChannels, int bytes,
* @param bits[] An array of length numChannels.
* Each entry is the number of bits composing the channel, in
* order starting at bit 0 of the packed type.
* @param paddings[] An array of length numChannels.
* Each entry is the number of padding bits after each channel.
* @param channels[] An array of length numChannels.
* Each entry enumerates the channel type: 0 = red, 1 = green,
* 2 = blue, 15 = alpha, in order starting at bit 0 of the
Expand All @@ -239,9 +243,9 @@ uint32_t *createDFDUnpacked(int bigEndian, int numChannels, int bytes,
* @return A data format descriptor in malloc'd data. The caller is responsible
* for freeing the descriptor.
**/
uint32_t *createDFDPacked(int bigEndian, int numChannels,
int bits[], int channels[],
enum VkSuffix suffix)
uint32_t *createDFDPackedPadded(int bigEndian, int numChannels,
int bits[], int paddings[], int channels[],
enum VkSuffix suffix)
{
uint32_t *DFD = 0;
if (numChannels == 6) {
Expand Down Expand Up @@ -287,7 +291,7 @@ uint32_t *createDFDPacked(int bigEndian, int numChannels,
int sampleCounter;
for (channelCounter = 0; channelCounter < numChannels; ++channelCounter) {
beChannelStart[channelCounter] = totalBits;
totalBits += bits[channelCounter];
totalBits += bits[channelCounter] + paddings[channelCounter];
}
BEMask = (totalBits - 1) & 0x18;
for (channelCounter = 0; channelCounter < numChannels; ++channelCounter) {
Expand All @@ -297,7 +301,7 @@ uint32_t *createDFDPacked(int bigEndian, int numChannels,
bitChannel[((bitOffset + bits[channelCounter] - 1) & ~7) ^ BEMask] = channelCounter;
numSamples++;
}
bitOffset += bits[channelCounter];
bitOffset += bits[channelCounter] + paddings[channelCounter];
}
DFD = writeHeader(numSamples, totalBits >> 3, suffix, i_COLOR);

Expand Down Expand Up @@ -339,7 +343,7 @@ uint32_t *createDFDPacked(int bigEndian, int numChannels,
int totalBits = 0;
int bitOffset = 0;
for (sampleCounter = 0; sampleCounter < numChannels; ++sampleCounter) {
totalBits += bits[sampleCounter];
totalBits += bits[sampleCounter] + paddings[sampleCounter];
}

/* One sample per channel */
Expand All @@ -348,12 +352,98 @@ uint32_t *createDFDPacked(int bigEndian, int numChannels,
writeSample(DFD, sampleCounter, channels[sampleCounter],
bits[sampleCounter], bitOffset,
1, 1, suffix);
bitOffset += bits[sampleCounter];
bitOffset += bits[sampleCounter] + paddings[sampleCounter];
}
}
return DFD;
}

/**
* @~English
* @brief Create a Data Format Descriptor for a packed format.
*
* @param bigEndian Big-endian flag: Set to 1 for big-endian byte ordering and
* 0 for little-endian byte ordering.
* @param numChannels The number of color channels.
* @param bits[] An array of length numChannels.
* Each entry is the number of bits composing the channel, in
* order starting at bit 0 of the packed type.
* @param channels[] An array of length numChannels.
* Each entry enumerates the channel type: 0 = red, 1 = green,
* 2 = blue, 15 = alpha, in order starting at bit 0 of the
* packed type. These values match channel IDs for RGBSDA in
* the Khronos Data Format header. To simplify iteration
* through channels, channel id 3 is a synonym for alpha.
* @param suffix Indicates the format suffix for the type.
*
* @return A data format descriptor in malloc'd data. The caller is responsible
* for freeing the descriptor.
**/
uint32_t *createDFDPacked(int bigEndian, int numChannels,
int bits[], int channels[],
enum VkSuffix suffix) {
assert(numChannels <= 6);
int paddings[] = {0, 0, 0, 0, 0, 0};
return createDFDPackedPadded(bigEndian, numChannels, bits, paddings, channels, suffix);
}

uint32_t *createDFD422(int bigEndian, int numSamples,
int bits[], int paddings[], int channels[],
int position_xs[], int position_ys[],
enum VkSuffix suffix) {
assert(!bigEndian); (void) bigEndian;
assert(suffix == s_UNORM); (void) suffix;

int totalBits = 0;
for (int i = 0; i < numSamples; ++i)
totalBits += bits[i] + paddings[i];
assert(totalBits % 8 == 0);

uint32_t BDFDSize = sizeof(uint32_t) * (KHR_DF_WORD_SAMPLESTART + numSamples * KHR_DF_WORD_SAMPLEWORDS);
uint32_t DFDSize = sizeof(uint32_t) + BDFDSize;
uint32_t *DFD = (uint32_t *) malloc(DFDSize);
memset(DFD, 0, DFDSize);
DFD[0] = DFDSize;
uint32_t *BDFD = DFD + 1;
KHR_DFDSETVAL(BDFD, VENDORID, KHR_DF_VENDORID_KHRONOS);
KHR_DFDSETVAL(BDFD, DESCRIPTORTYPE, KHR_DF_KHR_DESCRIPTORTYPE_BASICFORMAT);
KHR_DFDSETVAL(BDFD, VERSIONNUMBER, KHR_DF_VERSIONNUMBER_LATEST);
KHR_DFDSETVAL(BDFD, DESCRIPTORBLOCKSIZE, BDFDSize);
KHR_DFDSETVAL(BDFD, MODEL, KHR_DF_MODEL_YUVSDA);
KHR_DFDSETVAL(BDFD, PRIMARIES, KHR_DF_PRIMARIES_UNSPECIFIED);
KHR_DFDSETVAL(BDFD, TRANSFER, KHR_DF_TRANSFER_LINEAR);
KHR_DFDSETVAL(BDFD, FLAGS, KHR_DF_FLAG_ALPHA_STRAIGHT);
KHR_DFDSETVAL(BDFD, TEXELBLOCKDIMENSION0, 2 - 1); // 422 contains 2 x 1 blocks
KHR_DFDSETVAL(BDFD, TEXELBLOCKDIMENSION1, 1 - 1);
KHR_DFDSETVAL(BDFD, TEXELBLOCKDIMENSION2, 1 - 1);
KHR_DFDSETVAL(BDFD, TEXELBLOCKDIMENSION3, 1 - 1);
KHR_DFDSETVAL(BDFD, BYTESPLANE0, totalBits / 8);
KHR_DFDSETVAL(BDFD, BYTESPLANE1, 0);
KHR_DFDSETVAL(BDFD, BYTESPLANE2, 0);
KHR_DFDSETVAL(BDFD, BYTESPLANE3, 0);
KHR_DFDSETVAL(BDFD, BYTESPLANE4, 0);
KHR_DFDSETVAL(BDFD, BYTESPLANE5, 0);
KHR_DFDSETVAL(BDFD, BYTESPLANE6, 0);
KHR_DFDSETVAL(BDFD, BYTESPLANE7, 0);

int bitOffset = 0;
for (int i = 0; i < numSamples; ++i) {
KHR_DFDSETSVAL(BDFD, i, BITOFFSET, bitOffset);
KHR_DFDSETSVAL(BDFD, i, BITLENGTH, bits[i] - 1);
KHR_DFDSETSVAL(BDFD, i, CHANNELID, channels[i]);
KHR_DFDSETSVAL(BDFD, i, QUALIFIERS, 0); // None of: FLOAT, SIGNED, EXPONENT, LINEAR
KHR_DFDSETSVAL(BDFD, i, SAMPLEPOSITION0, position_xs[i]);
KHR_DFDSETSVAL(BDFD, i, SAMPLEPOSITION1, position_ys[i]);
KHR_DFDSETSVAL(BDFD, i, SAMPLEPOSITION2, 0);
KHR_DFDSETSVAL(BDFD, i, SAMPLEPOSITION3, 0);
KHR_DFDSETSVAL(BDFD, i, SAMPLELOWER, 0);
KHR_DFDSETSVAL(BDFD, i, SAMPLEUPPER, (1u << bits[i]) - 1u);
bitOffset += bits[i] + paddings[i];
}

return DFD;
}

static khr_df_model_e compModelMapping[] = {
KHR_DF_MODEL_BC1A, /*!< BC1, aka DXT1, no alpha. */
KHR_DF_MODEL_BC1A, /*!< BC1, aka DXT1, punch-through alpha. */
Expand Down
31 changes: 23 additions & 8 deletions lib/dfdutils/dfd.h
Original file line number Diff line number Diff line change
Expand Up @@ -73,11 +73,22 @@ uint32_t* vk2dfd(enum VkFormat format);
uint32_t *createDFDUnpacked(int bigEndian, int numChannels, int bytes,
int redBlueSwap, enum VkSuffix suffix);

/* Create a Data Format Descriptor for a packed padded format. */
uint32_t *createDFDPackedPadded(int bigEndian, int numChannels,
int bits[], int paddings[], int channels[],
enum VkSuffix suffix);

/* Create a Data Format Descriptor for a packed format. */
uint32_t *createDFDPacked(int bigEndian, int numChannels,
int bits[], int channels[],
enum VkSuffix suffix);

/* Create a Data Format Descriptor for a 4:2:2 format. */
uint32_t *createDFD422(int bigEndian, int numChannels,
int bits[], int paddings[], int channels[],
int position_xs[], int position_ys[],
enum VkSuffix suffix);

/* Create a Data Format Descriptor for a compressed format. */
uint32_t *createDFDCompressed(enum VkCompScheme compScheme,
int bwidth, int bheight, int bdepth,
Expand All @@ -91,13 +102,15 @@ uint32_t *createDFDDepthStencil(int depthBits,
/** @brief Result of interpreting the data format descriptor. */
enum InterpretDFDResult {
i_LITTLE_ENDIAN_FORMAT_BIT = 0, /*!< Confirmed little-endian (default for 8bpc). */
i_BIG_ENDIAN_FORMAT_BIT = 1, /*!< Confirmed big-endian. */
i_PACKED_FORMAT_BIT = 2, /*!< Packed format. */
i_SRGB_FORMAT_BIT = 4, /*!< sRGB transfer function. */
i_NORMALIZED_FORMAT_BIT = 8, /*!< Normalized (UNORM or SNORM). */
i_SIGNED_FORMAT_BIT = 16, /*!< Format is signed. */
i_FLOAT_FORMAT_BIT = 32, /*!< Format is floating point. */
i_UNSUPPORTED_ERROR_BIT = 64, /*!< Format not successfully interpreted. */
i_BIG_ENDIAN_FORMAT_BIT = 1u << 0u, /*!< Confirmed big-endian. */
i_PACKED_FORMAT_BIT = 1u << 1u, /*!< Packed format. */
i_SRGB_FORMAT_BIT = 1u << 2u, /*!< sRGB transfer function. */
i_NORMALIZED_FORMAT_BIT = 1u << 3u, /*!< Normalized (UNORM or SNORM). */
i_SIGNED_FORMAT_BIT = 1u << 4u, /*!< Format is signed. */
i_FLOAT_FORMAT_BIT = 1u << 5u, /*!< Format is floating point. */
i_COMPRESSED_FORMAT_BIT = 1u << 6u, /*!< Format is block compressed (422). */
i_YUVSDA_FORMAT_BIT = 1u << 7u, /*!< Color model is YUVSDA. */
i_UNSUPPORTED_ERROR_BIT = 1u << 8u, /*!< Format not successfully interpreted. */
/** "NONTRIVIAL_ENDIANNESS" means not big-endian, not little-endian
* (a channel has bits that are not consecutive in either order). **/
i_UNSUPPORTED_NONTRIVIAL_ENDIANNESS = i_UNSUPPORTED_ERROR_BIT,
Expand All @@ -110,7 +123,9 @@ enum InterpretDFDResult {
i_UNSUPPORTED_CHANNEL_TYPES = i_UNSUPPORTED_ERROR_BIT + 3,
/** Only channels with the same flags are supported
* (e.g. we don't support float red with integer green). */
i_UNSUPPORTED_MIXED_CHANNELS = i_UNSUPPORTED_ERROR_BIT + 4
i_UNSUPPORTED_MIXED_CHANNELS = i_UNSUPPORTED_ERROR_BIT + 4,
/** Only 2x1 block is supported for YUVSDA model. */
i_UNSUPPORTED_BLOCK_DIMENSIONS = i_UNSUPPORTED_ERROR_BIT + 5,
};

/** @brief Interpretation of a channel from the data format descriptor. */
Expand Down
Loading

0 comments on commit dbd9ff0

Please sign in to comment.