Skip to content

Commit

Permalink
Fix mPACKn formats (KhronosGroup#858)
Browse files Browse the repository at this point in the history
Fixes KhronosGroup#857. It also fixes the part of KhronosGroup#853 that is related to the
changes about `mPACKn` rules.

Both of these affected the `16X4` and `10X6` formats, so they were
addressed together.
  • Loading branch information
aqnuep authored Feb 13, 2024
1 parent 03d625a commit b464992
Show file tree
Hide file tree
Showing 11 changed files with 702 additions and 93 deletions.
1 change: 1 addition & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -389,6 +389,7 @@ set(KTX_MAIN_SRC
lib/vkformat_check.c
lib/vkformat_enum.h
lib/vkformat_str.c
lib/vkformat_typesize.c
)

set(BASISU_ENCODER_CXX_SRC
Expand Down
1 change: 1 addition & 0 deletions cmake/mkvk.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ list(APPEND mkvkformatfiles_input
lib/mkvkformatfiles)
list(APPEND mkvkformatfiles_output
"${PROJECT_SOURCE_DIR}/lib/vkformat_enum.h"
"${PROJECT_SOURCE_DIR}/lib/vkformat_typesize.c"
"${PROJECT_SOURCE_DIR}/lib/vkformat_check.c"
"${PROJECT_SOURCE_DIR}/lib/vkformat_str.c")

Expand Down
32 changes: 18 additions & 14 deletions lib/dfdutils/createdfd.c
Original file line number Diff line number Diff line change
Expand Up @@ -230,8 +230,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
Expand All @@ -243,9 +244,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) {
Expand Down Expand Up @@ -291,17 +292,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);

Expand Down Expand Up @@ -343,16 +345,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;
Expand Down Expand Up @@ -383,20 +386,20 @@ 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;
assert(suffix == s_UNORM); (void) suffix;

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);
Expand Down Expand Up @@ -428,6 +431,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]);
Expand All @@ -438,7 +442,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;
Expand Down
8 changes: 4 additions & 4 deletions lib/dfdutils/dfd.h
Original file line number Diff line number Diff line change
Expand Up @@ -74,9 +74,9 @@ 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,
Expand All @@ -85,7 +85,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);

Expand Down
36 changes: 18 additions & 18 deletions lib/dfdutils/makevk2dfd.pl
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ sub formatProcessed {
my $formatChannels = $1;

my $bits = "";
my $paddings = "";
my $shiftBits = "";
my $position_xs = "";
my $position_ys = "";
my $last_green = 1;
Expand All @@ -95,7 +95,7 @@ sub formatProcessed {
if ($channels ne "") {
$channels = ", " . $channels;
$bits = ", " . $bits;
$paddings = ", " . $paddings;
$shiftBits = ", " . $shiftBits;
$position_xs = ", " . $position_xs;
$position_ys = ", " . $position_ys;
}
Expand Down Expand Up @@ -134,16 +134,16 @@ sub formatProcessed {

$bits = $bit . $bits;

if ($padding ne "") { $paddings = $padding . $paddings; }
else { $paddings = "0" . $paddings; }
if ($padding ne "") { $shiftBits = $padding . $shiftBits; }
else { $shiftBits = "0" . $shiftBits; }

$formatChannels = $1;
}

print "case $format: {\n";
print " int channels[] = {$channels}; int bits[] = {$bits}; int paddings[] = {$paddings};\n";
print " int channels[] = {$channels}; int bits[] = {$bits}; int shiftBits[] = {$shiftBits};\n";
print " int position_xs[] = {$position_xs}; int position_ys[] = {$position_ys};\n";
print " return createDFD422($bigEndian, 4, bits, paddings, channels, position_xs, position_ys, s_UNORM);\n}\n";
print " return createDFD422($bigEndian, 4, bits, shiftBits, channels, position_xs, position_ys, s_UNORM);\n}\n";

} elsif ($line =~ m/VK_FORMAT_[RGBAE0-9]+_/) {
# Set $format to the enum identifier
Expand Down Expand Up @@ -308,48 +308,48 @@ sub formatProcessed {
if (!exists($foundFormats{$format})) {
$foundFormats{$format} = 1;
print "case $format: {\n";
print " int channels[] = {0}; int bits[] = {10}; int paddings[] = {6};\n";
print " return createDFDPackedPadded($bigEndian, 1, bits, paddings, channels, s_UNORM);\n}\n"
print " int channels[] = {0}; int bits[] = {10}; int shiftBits[] = {6};\n";
print " return createDFDPackedShifted($bigEndian, 1, bits, shiftBits, channels, s_UNORM);\n}\n"
}
} elsif ($line =~ m/(VK_FORMAT_R10X6G10X6_UNORM_2PACK16)/) {
$format = $1; # Extract the format identifier from the rest of the line
if (!exists($foundFormats{$format})) {
$foundFormats{$format} = 1;
print "case $format: {\n";
print " int channels[] = {0, 1}; int bits[] = {10, 10}; int paddings[] = {6, 6};\n";
print " return createDFDPackedPadded($bigEndian, 2, bits, paddings, channels, s_UNORM);\n}\n"
print " int channels[] = {0, 1}; int bits[] = {10, 10}; int shiftBits[] = {6, 6};\n";
print " return createDFDPackedShifted($bigEndian, 2, bits, shiftBits, channels, s_UNORM);\n}\n"
}
} elsif ($line =~ m/(VK_FORMAT_R10X6G10X6B10X6A10X6_UNORM_4PACK16)/) {
$format = $1; # Extract the format identifier from the rest of the line
if (!exists($foundFormats{$format})) {
$foundFormats{$format} = 1;
print "case $format: {\n";
print " int channels[] = {0, 1, 2, 3}; int bits[] = {10, 10, 10, 10}; int paddings[] = {6, 6, 6, 6};\n";
print " return createDFDPackedPadded($bigEndian, 4, bits, paddings, channels, s_UNORM);\n}\n"
print " int channels[] = {0, 1, 2, 3}; int bits[] = {10, 10, 10, 10}; int shiftBits[] = {6, 6, 6, 6};\n";
print " return createDFDPackedShifted($bigEndian, 4, bits, shiftBits, channels, s_UNORM);\n}\n"
}
} elsif ($line =~ m/(VK_FORMAT_R12X4_UNORM_PACK16)/) {
$format = $1; # Extract the format identifier from the rest of the line
if (!exists($foundFormats{$format})) {
$foundFormats{$format} = 1;
print "case $format: {\n";
print " int channels[] = {0}; int bits[] = {12}; int paddings[] = {4};\n";
print " return createDFDPackedPadded($bigEndian, 1, bits, paddings, channels, s_UNORM);\n}\n"
print " int channels[] = {0}; int bits[] = {12}; int shiftBits[] = {4};\n";
print " return createDFDPackedShifted($bigEndian, 1, bits, shiftBits, channels, s_UNORM);\n}\n"
}
} elsif ($line =~ m/(VK_FORMAT_R12X4G12X4_UNORM_2PACK16)/) {
$format = $1; # Extract the format identifier from the rest of the line
if (!exists($foundFormats{$format})) {
$foundFormats{$format} = 1;
print "case $format: {\n";
print " int channels[] = {0, 1}; int bits[] = {12, 12}; int paddings[] = {4, 4};\n";
print " return createDFDPackedPadded($bigEndian, 2, bits, paddings, channels, s_UNORM);\n}\n"
print " int channels[] = {0, 1}; int bits[] = {12, 12}; int shiftBits[] = {4, 4};\n";
print " return createDFDPackedShifted($bigEndian, 2, bits, shiftBits, channels, s_UNORM);\n}\n"
}
} elsif ($line =~ m/(VK_FORMAT_R12X4G12X4B12X4A12X4_UNORM_4PACK16)/) {
$format = $1; # Extract the format identifier from the rest of the line
if (!exists($foundFormats{$format})) {
$foundFormats{$format} = 1;
print "case $format: {\n";
print " int channels[] = {0, 1, 2, 3}; int bits[] = {12, 12, 12, 12}; int paddings[] = {4, 4, 4, 4};\n";
print " return createDFDPackedPadded($bigEndian, 4, bits, paddings, channels, s_UNORM);\n}\n"
print " int channels[] = {0, 1, 2, 3}; int bits[] = {12, 12, 12, 12}; int shiftBits[] = {4, 4, 4, 4};\n";
print " return createDFDPackedShifted($bigEndian, 4, bits, shiftBits, channels, s_UNORM);\n}\n"
}

# If we weren't VK_FORMAT_ plus a channel, we might be a compressed
Expand Down
56 changes: 28 additions & 28 deletions lib/dfdutils/vk2dfd.inl
Original file line number Diff line number Diff line change
Expand Up @@ -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};
Expand Down
1 change: 1 addition & 0 deletions lib/internalexport.def
Original file line number Diff line number Diff line change
Expand Up @@ -45,4 +45,5 @@ EXPORTS
ktxTexture2_destruct
vk2dfd
vkFormatString
vkFormatTypeSize
stringToVkFormat
1 change: 1 addition & 0 deletions lib/internalexport_mingw.def
Original file line number Diff line number Diff line change
Expand Up @@ -45,4 +45,5 @@ EXPORTS
ktxTexture2_destruct
vk2dfd
vkFormatString
vkFormatTypeSize
stringToVkFormat
Loading

0 comments on commit b464992

Please sign in to comment.