123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660 |
- /* -*- tab-width: 4; -*- */
- /* vi: set sw=2 ts=4 expandtab: */
- /* Copyright 2019-2020 The Khronos Group Inc.
- * SPDX-License-Identifier: Apache-2.0
- */
- /**
- * @file
- * @~English
- * @brief Utilities for creating data format descriptors.
- */
- /*
- * Author: Andrew Garrard
- */
- #include <stdlib.h>
- #include <KHR/khr_df.h>
- #include "dfd.h"
- typedef enum { i_COLOR, i_NON_COLOR } channels_infotype;
- static uint32_t *writeHeader(int numSamples, int bytes, int suffix,
- channels_infotype infotype)
- {
- uint32_t *DFD = (uint32_t *) malloc(sizeof(uint32_t) *
- (1 + KHR_DF_WORD_SAMPLESTART +
- numSamples * KHR_DF_WORD_SAMPLEWORDS));
- uint32_t* BDFD = DFD+1;
- DFD[0] = sizeof(uint32_t) *
- (1 + KHR_DF_WORD_SAMPLESTART +
- numSamples * KHR_DF_WORD_SAMPLEWORDS);
- BDFD[KHR_DF_WORD_VENDORID] =
- (KHR_DF_VENDORID_KHRONOS << KHR_DF_SHIFT_VENDORID) |
- (KHR_DF_KHR_DESCRIPTORTYPE_BASICFORMAT << KHR_DF_SHIFT_DESCRIPTORTYPE);
- BDFD[KHR_DF_WORD_VERSIONNUMBER] =
- (KHR_DF_VERSIONNUMBER_LATEST << KHR_DF_SHIFT_VERSIONNUMBER) |
- (((uint32_t)sizeof(uint32_t) *
- (KHR_DF_WORD_SAMPLESTART +
- numSamples * KHR_DF_WORD_SAMPLEWORDS)
- << KHR_DF_SHIFT_DESCRIPTORBLOCKSIZE));
- BDFD[KHR_DF_WORD_MODEL] =
- ((KHR_DF_MODEL_RGBSDA << KHR_DF_SHIFT_MODEL) | /* Only supported model */
- (KHR_DF_FLAG_ALPHA_STRAIGHT << KHR_DF_SHIFT_FLAGS));
- if (infotype == i_COLOR) {
- BDFD[KHR_DF_WORD_PRIMARIES] |= KHR_DF_PRIMARIES_BT709 << KHR_DF_SHIFT_PRIMARIES; /* Assumed */
- } else {
- BDFD[KHR_DF_WORD_PRIMARIES] |= KHR_DF_PRIMARIES_UNSPECIFIED << KHR_DF_SHIFT_PRIMARIES;
- }
- if (suffix == s_SRGB) {
- BDFD[KHR_DF_WORD_TRANSFER] |= KHR_DF_TRANSFER_SRGB << KHR_DF_SHIFT_TRANSFER;
- } else {
- BDFD[KHR_DF_WORD_TRANSFER] |= KHR_DF_TRANSFER_LINEAR << KHR_DF_SHIFT_TRANSFER;
- }
- BDFD[KHR_DF_WORD_TEXELBLOCKDIMENSION0] = 0; /* Only 1x1x1x1 texel blocks supported */
- BDFD[KHR_DF_WORD_BYTESPLANE0] = bytes; /* bytesPlane0 = bytes, bytesPlane3..1 = 0 */
- BDFD[KHR_DF_WORD_BYTESPLANE4] = 0; /* bytesPlane7..5 = 0 */
- return DFD;
- }
- static uint32_t setChannelFlags(uint32_t channel, enum VkSuffix suffix)
- {
- switch (suffix) {
- case s_UNORM: break;
- case s_SNORM:
- channel |=
- KHR_DF_SAMPLE_DATATYPE_SIGNED;
- break;
- case s_USCALED: break;
- case s_SSCALED:
- channel |=
- KHR_DF_SAMPLE_DATATYPE_SIGNED;
- break;
- case s_UINT: break;
- case s_SINT:
- channel |=
- KHR_DF_SAMPLE_DATATYPE_SIGNED;
- break;
- case s_SFLOAT:
- channel |=
- KHR_DF_SAMPLE_DATATYPE_FLOAT |
- KHR_DF_SAMPLE_DATATYPE_SIGNED;
- break;
- case s_UFLOAT:
- channel |=
- KHR_DF_SAMPLE_DATATYPE_FLOAT;
- break;
- case s_SRGB:
- if (channel == KHR_DF_CHANNEL_RGBSDA_ALPHA) {
- channel |= KHR_DF_SAMPLE_DATATYPE_LINEAR;
- }
- break;
- }
- return channel;
- }
- static void writeSample(uint32_t *DFD, int sampleNo, int channel,
- int bits, int offset,
- int topSample, int bottomSample, enum VkSuffix suffix)
- {
- // Use this to avoid type-punning complaints from the gcc optimizer
- // with -Wall.
- union {
- uint32_t i;
- 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);
- sample[KHR_DF_SAMPLEWORD_BITOFFSET] =
- (offset << KHR_DF_SAMPLESHIFT_BITOFFSET) |
- ((bits - 1) << KHR_DF_SAMPLESHIFT_BITLENGTH) |
- (channel << KHR_DF_SAMPLESHIFT_CHANNELID);
- sample[KHR_DF_SAMPLEWORD_SAMPLEPOSITION_ALL] = 0;
- switch (suffix) {
- case s_UNORM:
- case s_SRGB:
- default:
- if (bits > 32) {
- upper.i = 0xFFFFFFFFU;
- } else {
- upper.i = (uint32_t)((1U << bits) - 1U);
- }
- lower.i = 0U;
- break;
- case s_SNORM:
- if (bits > 32) {
- upper.i = 0x7FFFFFFF;
- } else {
- upper.i = topSample ? (1U << (bits - 1)) - 1 : (1U << bits) - 1;
- }
- lower.i = ~upper.i;
- if (bottomSample) lower.i += 1;
- break;
- case s_USCALED:
- case s_UINT:
- upper.i = bottomSample ? 1U : 0U;
- lower.i = 0U;
- break;
- case s_SSCALED:
- case s_SINT:
- upper.i = bottomSample ? 1U : 0U;
- lower.i = ~0U;
- break;
- case s_SFLOAT:
- upper.f = 1.0f;
- lower.f = -1.0f;
- break;
- case s_UFLOAT:
- upper.f = 1.0f;
- lower.f = 0.0f;
- break;
- }
- sample[KHR_DF_SAMPLEWORD_SAMPLELOWER] = lower.i;
- sample[KHR_DF_SAMPLEWORD_SAMPLEUPPER] = upper.i;
- }
- /**
- * @~English
- * @brief Create a Data Format Descriptor for an unpacked format.
- *
- * @param bigEndian Set to 1 for big-endian byte ordering and
- 0 for little-endian byte ordering.
- * @param numChannels The number of color channels.
- * @param bytes The number of bytes per channel.
- * @param redBlueSwap Normally channels appear in consecutive R, G, B, A order
- * in memory; redBlueSwap inverts red and blue, allowing
- * B, G, R, A.
- * @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 *createDFDUnpacked(int bigEndian, int numChannels, int bytes,
- int redBlueSwap, enum VkSuffix suffix)
- {
- uint32_t *DFD;
- if (bigEndian) {
- int channelCounter, channelByte;
- /* Number of samples = number of channels * bytes per channel */
- DFD = writeHeader(numChannels * bytes, numChannels * bytes, suffix, i_COLOR);
- /* First loop over the channels */
- for (channelCounter = 0; channelCounter < numChannels; ++channelCounter) {
- int channel = channelCounter;
- if (redBlueSwap && (channel == 0 || channel == 2)) {
- channel ^= 2;
- }
- /* Loop over the bytes that constitute a channel */
- for (channelByte = 0; channelByte < bytes; ++channelByte) {
- writeSample(DFD, channelCounter * bytes + channelByte, channel,
- 8, 8 * (channelCounter * bytes + bytes - channelByte - 1),
- channelByte == bytes-1, channelByte == 0, suffix);
- }
- }
- } else { /* Little-endian */
- int sampleCounter;
- /* One sample per channel */
- DFD = writeHeader(numChannels, numChannels * bytes, suffix, i_COLOR);
- for (sampleCounter = 0; sampleCounter < numChannels; ++sampleCounter) {
- int channel = sampleCounter;
- if (redBlueSwap && (channel == 0 || channel == 2)) {
- channel ^= 2;
- }
- writeSample(DFD, sampleCounter, channel,
- 8 * bytes, 8 * sampleCounter * bytes,
- 1, 1, suffix);
- }
- }
- 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)
- {
- uint32_t *DFD = 0;
- if (numChannels == 6) {
- /* Special case E5B9G9R9 */
- DFD = writeHeader(numChannels, 4, s_UFLOAT, i_COLOR);
- writeSample(DFD, 0, 0,
- 9, 0,
- 1, 1, s_UNORM);
- KHR_DFDSETSVAL((DFD+1), 0, SAMPLEUPPER, 8448);
- writeSample(DFD, 1, 0 | KHR_DF_SAMPLE_DATATYPE_EXPONENT,
- 5, 27,
- 1, 1, s_UNORM);
- KHR_DFDSETSVAL((DFD+1), 1, SAMPLELOWER, 15);
- KHR_DFDSETSVAL((DFD+1), 1, SAMPLEUPPER, 31);
- writeSample(DFD, 2, 1,
- 9, 9,
- 1, 1, s_UNORM);
- KHR_DFDSETSVAL((DFD+1), 2, SAMPLEUPPER, 8448);
- writeSample(DFD, 3, 1 | KHR_DF_SAMPLE_DATATYPE_EXPONENT,
- 5, 27,
- 1, 1, s_UNORM);
- KHR_DFDSETSVAL((DFD+1), 3, SAMPLELOWER, 15);
- KHR_DFDSETSVAL((DFD+1), 3, SAMPLEUPPER, 31);
- writeSample(DFD, 4, 2,
- 9, 18,
- 1, 1, s_UNORM);
- KHR_DFDSETSVAL((DFD+1), 4, SAMPLEUPPER, 8448);
- writeSample(DFD, 5, 2 | KHR_DF_SAMPLE_DATATYPE_EXPONENT,
- 5, 27,
- 1, 1, s_UNORM);
- KHR_DFDSETSVAL((DFD+1), 5, SAMPLELOWER, 15);
- KHR_DFDSETSVAL((DFD+1), 5, SAMPLEUPPER, 31);
- } else if (bigEndian) {
- /* No packed format is larger than 32 bits. */
- /* No packed channel crosses more than two bytes. */
- int totalBits = 0;
- int bitChannel[32];
- int beChannelStart[4];
- int channelCounter;
- int bitOffset = 0;
- int BEMask;
- int numSamples = numChannels;
- int sampleCounter;
- for (channelCounter = 0; channelCounter < numChannels; ++channelCounter) {
- beChannelStart[channelCounter] = totalBits;
- totalBits += bits[channelCounter];
- }
- BEMask = (totalBits - 1) & 0x18;
- for (channelCounter = 0; channelCounter < numChannels; ++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];
- }
- DFD = writeHeader(numSamples, totalBits >> 3, suffix, i_COLOR);
- sampleCounter = 0;
- for (bitOffset = 0; bitOffset < totalBits;) {
- if (bitChannel[bitOffset] == -1) {
- /* Done this bit, so this is the lower half of something. */
- /* We must therefore jump to the end of the byte and continue. */
- bitOffset = (bitOffset + 8) & ~7;
- } else {
- /* Start of a channel? */
- int thisChannel = bitChannel[bitOffset];
- if ((beChannelStart[thisChannel] ^ BEMask) == bitOffset) {
- /* Must be just one sample if we hit it first. */
- writeSample(DFD, sampleCounter++, channels[thisChannel],
- bits[thisChannel], bitOffset,
- 1, 1, suffix);
- bitOffset += bits[thisChannel];
- } else {
- /* Two samples. Move to the end of the first one we hit when we're done. */
- int firstSampleBits = 8 - (beChannelStart[thisChannel] & 0x7); /* Rest of the byte */
- int secondSampleBits = bits[thisChannel] - firstSampleBits; /* Rest of the bits */
- writeSample(DFD, sampleCounter++, channels[thisChannel],
- firstSampleBits, beChannelStart[thisChannel] ^ BEMask,
- 0, 1, suffix);
- /* Mark that we've already handled this sample */
- bitChannel[beChannelStart[thisChannel] ^ BEMask] = -1;
- writeSample(DFD, sampleCounter++, channels[thisChannel],
- secondSampleBits, bitOffset,
- 1, 0, suffix);
- bitOffset += secondSampleBits;
- }
- }
- }
- } else { /* Little-endian */
- int sampleCounter;
- int totalBits = 0;
- int bitOffset = 0;
- for (sampleCounter = 0; sampleCounter < numChannels; ++sampleCounter) {
- totalBits += bits[sampleCounter];
- }
- /* One sample per channel */
- DFD = writeHeader(numChannels, totalBits >> 3, suffix, i_COLOR);
- for (sampleCounter = 0; sampleCounter < numChannels; ++sampleCounter) {
- writeSample(DFD, sampleCounter, channels[sampleCounter],
- bits[sampleCounter], bitOffset,
- 1, 1, suffix);
- bitOffset += bits[sampleCounter];
- }
- }
- 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. */
- KHR_DF_MODEL_BC2, /*!< BC2, aka DXT2 and DXT3. */
- KHR_DF_MODEL_BC3, /*!< BC3, aka DXT4 and DXT5. */
- KHR_DF_MODEL_BC4, /*!< BC4. */
- KHR_DF_MODEL_BC5, /*!< BC5. */
- KHR_DF_MODEL_BC6H, /*!< BC6h HDR format. */
- KHR_DF_MODEL_BC7, /*!< BC7. */
- KHR_DF_MODEL_ETC2, /*!< ETC2 no alpha. */
- KHR_DF_MODEL_ETC2, /*!< ETC2 punch-through alpha. */
- KHR_DF_MODEL_ETC2, /*!< ETC2 independent alpha. */
- KHR_DF_MODEL_ETC2, /*!< R11 ETC2 single-channel. */
- KHR_DF_MODEL_ETC2, /*!< R11G11 ETC2 dual-channel. */
- KHR_DF_MODEL_ASTC, /*!< ASTC. */
- KHR_DF_MODEL_ETC1S, /*!< ETC1S. */
- KHR_DF_MODEL_PVRTC, /*!< PVRTC(1). */
- KHR_DF_MODEL_PVRTC2 /*!< PVRTC2. */
- };
- static uint32_t compSampleCount[] = {
- 1U, /*!< BC1, aka DXT1, no alpha. */
- 1U, /*!< BC1, aka DXT1, punch-through alpha. */
- 2U, /*!< BC2, aka DXT2 and DXT3. */
- 2U, /*!< BC3, aka DXT4 and DXT5. */
- 1U, /*!< BC4. */
- 2U, /*!< BC5. */
- 1U, /*!< BC6h HDR format. */
- 1U, /*!< BC7. */
- 1U, /*!< ETC2 no alpha. */
- 2U, /*!< ETC2 punch-through alpha. */
- 2U, /*!< ETC2 independent alpha. */
- 1U, /*!< R11 ETC2 single-channel. */
- 2U, /*!< R11G11 ETC2 dual-channel. */
- 1U, /*!< ASTC. */
- 1U, /*!< ETC1S. */
- 1U, /*!< PVRTC. */
- 1U /*!< PVRTC2. */
- };
- static khr_df_model_channels_e compFirstChannel[] = {
- KHR_DF_CHANNEL_BC1A_COLOR, /*!< BC1, aka DXT1, no alpha. */
- KHR_DF_CHANNEL_BC1A_ALPHAPRESENT, /*!< BC1, aka DXT1, punch-through alpha. */
- KHR_DF_CHANNEL_BC2_ALPHA, /*!< BC2, aka DXT2 and DXT3. */
- KHR_DF_CHANNEL_BC3_ALPHA, /*!< BC3, aka DXT4 and DXT5. */
- KHR_DF_CHANNEL_BC4_DATA, /*!< BC4. */
- KHR_DF_CHANNEL_BC5_RED, /*!< BC5. */
- KHR_DF_CHANNEL_BC6H_COLOR, /*!< BC6h HDR format. */
- KHR_DF_CHANNEL_BC7_COLOR, /*!< BC7. */
- KHR_DF_CHANNEL_ETC2_COLOR, /*!< ETC2 no alpha. */
- KHR_DF_CHANNEL_ETC2_COLOR, /*!< ETC2 punch-through alpha. */
- KHR_DF_CHANNEL_ETC2_ALPHA, /*!< ETC2 independent alpha. */
- KHR_DF_CHANNEL_ETC2_RED, /*!< R11 ETC2 single-channel. */
- KHR_DF_CHANNEL_ETC2_RED, /*!< R11G11 ETC2 dual-channel. */
- KHR_DF_CHANNEL_ASTC_DATA, /*!< ASTC. */
- KHR_DF_CHANNEL_ETC1S_RGB, /*!< ETC1S. */
- KHR_DF_CHANNEL_PVRTC_COLOR, /*!< PVRTC. */
- KHR_DF_CHANNEL_PVRTC2_COLOR /*!< PVRTC2. */
- };
- static khr_df_model_channels_e compSecondChannel[] = {
- KHR_DF_CHANNEL_BC1A_COLOR, /*!< BC1, aka DXT1, no alpha. */
- KHR_DF_CHANNEL_BC1A_ALPHAPRESENT, /*!< BC1, aka DXT1, punch-through alpha. */
- KHR_DF_CHANNEL_BC2_COLOR, /*!< BC2, aka DXT2 and DXT3. */
- KHR_DF_CHANNEL_BC3_COLOR, /*!< BC3, aka DXT4 and DXT5. */
- KHR_DF_CHANNEL_BC4_DATA, /*!< BC4. */
- KHR_DF_CHANNEL_BC5_GREEN, /*!< BC5. */
- KHR_DF_CHANNEL_BC6H_COLOR, /*!< BC6h HDR format. */
- KHR_DF_CHANNEL_BC7_COLOR, /*!< BC7. */
- KHR_DF_CHANNEL_ETC2_COLOR, /*!< ETC2 no alpha. */
- KHR_DF_CHANNEL_ETC2_ALPHA, /*!< ETC2 punch-through alpha. */
- KHR_DF_CHANNEL_ETC2_COLOR, /*!< ETC2 independent alpha. */
- KHR_DF_CHANNEL_ETC2_RED, /*!< R11 ETC2 single-channel. */
- KHR_DF_CHANNEL_ETC2_GREEN, /*!< R11G11 ETC2 dual-channel. */
- KHR_DF_CHANNEL_ASTC_DATA, /*!< ASTC. */
- KHR_DF_CHANNEL_ETC1S_RGB, /*!< ETC1S. */
- KHR_DF_CHANNEL_PVRTC_COLOR, /*!< PVRTC. */
- KHR_DF_CHANNEL_PVRTC2_COLOR /*!< PVRTC2. */
- };
- static uint32_t compSecondChannelOffset[] = {
- 0U, /*!< BC1, aka DXT1, no alpha. */
- 0U, /*!< BC1, aka DXT1, punch-through alpha. */
- 64U, /*!< BC2, aka DXT2 and DXT3. */
- 64U, /*!< BC3, aka DXT4 and DXT5. */
- 0U, /*!< BC4. */
- 64U, /*!< BC5. */
- 0U, /*!< BC6h HDR format. */
- 0U, /*!< BC7. */
- 0U, /*!< ETC2 no alpha. */
- 0U, /*!< ETC2 punch-through alpha. */
- 64U, /*!< ETC2 independent alpha. */
- 0U, /*!< R11 ETC2 single-channel. */
- 64U, /*!< R11G11 ETC2 dual-channel. */
- 0U, /*!< ASTC. */
- 0U, /*!< ETC1S. */
- 0U, /*!< PVRTC. */
- 0U /*!< PVRTC2. */
- };
- static uint32_t compChannelBits[] = {
- 64U, /*!< BC1, aka DXT1, no alpha. */
- 64U, /*!< BC1, aka DXT1, punch-through alpha. */
- 64U, /*!< BC2, aka DXT2 and DXT3. */
- 64U, /*!< BC3, aka DXT4 and DXT5. */
- 64U, /*!< BC4. */
- 64U, /*!< BC5. */
- 128U, /*!< BC6h HDR format. */
- 128U, /*!< BC7. */
- 64U, /*!< ETC2 no alpha. */
- 64U, /*!< ETC2 punch-through alpha. */
- 64U, /*!< ETC2 independent alpha. */
- 64U, /*!< R11 ETC2 single-channel. */
- 64U, /*!< R11G11 ETC2 dual-channel. */
- 128U, /*!< ASTC. */
- 64U, /*!< ETC1S. */
- 64U, /*!< PVRTC. */
- 64U /*!< PVRTC2. */
- };
- static uint32_t compBytes[] = {
- 8U, /*!< BC1, aka DXT1, no alpha. */
- 8U, /*!< BC1, aka DXT1, punch-through alpha. */
- 16U, /*!< BC2, aka DXT2 and DXT3. */
- 16U, /*!< BC3, aka DXT4 and DXT5. */
- 8U, /*!< BC4. */
- 16U, /*!< BC5. */
- 16U, /*!< BC6h HDR format. */
- 16U, /*!< BC7. */
- 8U, /*!< ETC2 no alpha. */
- 8U, /*!< ETC2 punch-through alpha. */
- 16U, /*!< ETC2 independent alpha. */
- 8U, /*!< R11 ETC2 single-channel. */
- 16U, /*!< R11G11 ETC2 dual-channel. */
- 16U, /*!< ASTC. */
- 8U, /*!< ETC1S. */
- 8U, /*!< PVRTC. */
- 8U /*!< PVRTC2. */
- };
- /**
- * @~English
- * @brief Create a Data Format Descriptor for a compressed format.
- *
- * @param compScheme Vulkan-style compression scheme enumeration.
- * @param bwidth Block width in texel coordinates.
- * @param bheight Block height in texel coordinates.
- * @param bdepth Block depth in texel coordinates.
- * @author Mark Callow, Edgewise Consulting.
- * @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 *createDFDCompressed(enum VkCompScheme compScheme, int bwidth, int bheight, int bdepth,
- enum VkSuffix suffix)
- {
- uint32_t *DFD = 0;
- uint32_t numSamples = compSampleCount[compScheme];
- uint32_t* BDFD;
- uint32_t *sample;
- uint32_t channel;
- // Use union to avoid type-punning complaints from gcc optimizer
- // with -Wall.
- union {
- uint32_t i;
- float f;
- } lower, upper;
- DFD = (uint32_t *) malloc(sizeof(uint32_t) *
- (1 + KHR_DF_WORD_SAMPLESTART +
- numSamples * KHR_DF_WORD_SAMPLEWORDS));
- BDFD = DFD+1;
- DFD[0] = sizeof(uint32_t) *
- (1 + KHR_DF_WORD_SAMPLESTART +
- numSamples * KHR_DF_WORD_SAMPLEWORDS);
- BDFD[KHR_DF_WORD_VENDORID] =
- (KHR_DF_VENDORID_KHRONOS << KHR_DF_SHIFT_VENDORID) |
- (KHR_DF_KHR_DESCRIPTORTYPE_BASICFORMAT << KHR_DF_SHIFT_DESCRIPTORTYPE);
- BDFD[KHR_DF_WORD_VERSIONNUMBER] =
- (KHR_DF_VERSIONNUMBER_LATEST << KHR_DF_SHIFT_VERSIONNUMBER) |
- (((uint32_t)sizeof(uint32_t) *
- (KHR_DF_WORD_SAMPLESTART +
- numSamples * KHR_DF_WORD_SAMPLEWORDS)
- << KHR_DF_SHIFT_DESCRIPTORBLOCKSIZE));
- BDFD[KHR_DF_WORD_MODEL] =
- ((compModelMapping[compScheme] << KHR_DF_SHIFT_MODEL) |
- (KHR_DF_PRIMARIES_BT709 << KHR_DF_SHIFT_PRIMARIES) | /* Assumed */
- (KHR_DF_FLAG_ALPHA_STRAIGHT << KHR_DF_SHIFT_FLAGS));
- if (suffix == s_SRGB) {
- BDFD[KHR_DF_WORD_TRANSFER] |= KHR_DF_TRANSFER_SRGB << KHR_DF_SHIFT_TRANSFER;
- } else {
- BDFD[KHR_DF_WORD_TRANSFER] |= KHR_DF_TRANSFER_LINEAR << KHR_DF_SHIFT_TRANSFER;
- }
- BDFD[KHR_DF_WORD_TEXELBLOCKDIMENSION0] =
- (bwidth - 1) | ((bheight - 1) << KHR_DF_SHIFT_TEXELBLOCKDIMENSION1) | ((bdepth - 1) << KHR_DF_SHIFT_TEXELBLOCKDIMENSION2);
- /* bytesPlane0 = bytes, bytesPlane3..1 = 0 */
- BDFD[KHR_DF_WORD_BYTESPLANE0] = compBytes[compScheme];
- BDFD[KHR_DF_WORD_BYTESPLANE4] = 0; /* bytesPlane7..5 = 0 */
- sample = BDFD + KHR_DF_WORD_SAMPLESTART;
- channel = compFirstChannel[compScheme];
- channel = setChannelFlags(channel, suffix);
- sample[KHR_DF_SAMPLEWORD_BITOFFSET] =
- (0 << KHR_DF_SAMPLESHIFT_BITOFFSET) |
- ((compChannelBits[compScheme] - 1) << KHR_DF_SAMPLESHIFT_BITLENGTH) |
- (channel << KHR_DF_SAMPLESHIFT_CHANNELID);
- sample[KHR_DF_SAMPLEWORD_SAMPLEPOSITION_ALL] = 0;
- switch (suffix) {
- case s_UNORM:
- case s_SRGB:
- default:
- upper.i = 0xFFFFFFFFU;
- lower.i = 0U;
- break;
- case s_SNORM:
- upper.i = 0x7FFFFFFF;
- lower.i = ~upper.i;
- break;
- case s_USCALED:
- case s_UINT:
- upper.i = 1U;
- lower.i = 0U;
- break;
- case s_SSCALED:
- case s_SINT:
- upper.i = 1U;
- lower.i = ~0U;
- break;
- case s_SFLOAT:
- upper.f = 1.0f;
- lower.f = -1.0f;
- break;
- case s_UFLOAT:
- upper.f = 1.0f;
- lower.f = 0.0f;
- break;
- }
- sample[KHR_DF_SAMPLEWORD_SAMPLELOWER] = lower.i;
- sample[KHR_DF_SAMPLEWORD_SAMPLEUPPER] = upper.i;
- if (compSampleCount[compScheme] > 1) {
- sample += KHR_DF_WORD_SAMPLEWORDS;
- channel = compSecondChannel[compScheme];
- channel = setChannelFlags(channel, suffix);
- sample[KHR_DF_SAMPLEWORD_BITOFFSET] =
- (compSecondChannelOffset[compScheme] << KHR_DF_SAMPLESHIFT_BITOFFSET) |
- ((compChannelBits[compScheme] - 1) << KHR_DF_SAMPLESHIFT_BITLENGTH) |
- (channel << KHR_DF_SAMPLESHIFT_CHANNELID);
- sample[KHR_DF_SAMPLEWORD_SAMPLEPOSITION_ALL] = 0;
- sample[KHR_DF_SAMPLEWORD_SAMPLELOWER] = lower.i;
- sample[KHR_DF_SAMPLEWORD_SAMPLEUPPER] = upper.i;
- }
- return DFD;
- }
- /**
- * @~English
- * @brief Create a Data Format Descriptor for a depth-stencil format.
- *
- * @param depthBits The numeber of bits in the depth channel.
- * @param stencilBits The numeber of bits in the stencil channel.
- * @param sizeBytes The total byte size of the texel.
- *
- * @return A data format descriptor in malloc'd data. The caller is responsible
- * for freeing the descriptor.
- **/
- uint32_t *createDFDDepthStencil(int depthBits,
- int stencilBits,
- int sizeBytes)
- {
- /* N.B. Little-endian is assumed. */
- uint32_t *DFD = 0;
- DFD = writeHeader((depthBits > 0) + (stencilBits > 0),
- sizeBytes, s_UNORM, i_NON_COLOR);
- if (depthBits == 32) {
- writeSample(DFD, 0, KHR_DF_CHANNEL_RGBSDA_DEPTH,
- 32, 0,
- 1, 1, s_SFLOAT);
- } else if (depthBits > 0) {
- writeSample(DFD, 0, KHR_DF_CHANNEL_RGBSDA_DEPTH,
- depthBits, 0,
- 1, 1, s_UNORM);
- }
- if (stencilBits > 0) {
- if (depthBits > 0) {
- writeSample(DFD, 1, KHR_DF_CHANNEL_RGBSDA_STENCIL,
- stencilBits, depthBits,
- 1, 1, s_UINT);
- } else {
- writeSample(DFD, 0, KHR_DF_CHANNEL_RGBSDA_STENCIL,
- stencilBits, 0,
- 1, 1, s_UINT);
- }
- }
- return DFD;
- }
|