diff --git a/CMakeLists.txt b/CMakeLists.txt index 79a37b1e93..f1d37cf7a4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -179,11 +179,11 @@ set(KTX_MAIN_SRC lib/dfdutils/createdfd.c lib/dfdutils/colourspaces.c lib/dfdutils/dfd.h - lib/dfdutils/dfd2vk.inl lib/dfdutils/interpretdfd.c lib/dfdutils/printdfd.c lib/dfdutils/queries.c lib/dfdutils/vk2dfd.c + lib/dfdutils/vk2dfd.inl lib/dfdutils/vulkan/vk_platform.h lib/dfdutils/vulkan/vulkan_core.h lib/etcdec.cxx diff --git a/lib/dfdutils/createdfd.c b/lib/dfdutils/createdfd.c index 3fc90034a8..ea00d8d745 100644 --- a/lib/dfdutils/createdfd.c +++ b/lib/dfdutils/createdfd.c @@ -20,7 +20,10 @@ #include "dfd.h" -static uint32_t *writeHeader(int numSamples, int bytes, int suffix) +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 + @@ -40,8 +43,12 @@ static uint32_t *writeHeader(int numSamples, int bytes, int suffix) << KHR_DF_SHIFT_DESCRIPTORBLOCKSIZE)); BDFD[KHR_DF_WORD_MODEL] = ((KHR_DF_MODEL_RGBSDA << KHR_DF_SHIFT_MODEL) | /* Only supported model */ - (KHR_DF_PRIMARIES_BT709 << KHR_DF_SHIFT_PRIMARIES) | /* Assumed */ (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 { @@ -178,7 +185,7 @@ uint32_t *createDFDUnpacked(int bigEndian, int numChannels, int bytes, if (bigEndian) { int channelCounter, channelByte; /* Number of samples = number of channels * bytes per channel */ - DFD = writeHeader(numChannels * bytes, numChannels * bytes, suffix); + DFD = writeHeader(numChannels * bytes, numChannels * bytes, suffix, i_COLOR); /* First loop over the channels */ for (channelCounter = 0; channelCounter < numChannels; ++channelCounter) { int channel = channelCounter; @@ -197,7 +204,7 @@ uint32_t *createDFDUnpacked(int bigEndian, int numChannels, int bytes, int sampleCounter; /* One sample per channel */ - DFD = writeHeader(numChannels, numChannels * bytes, suffix); + DFD = writeHeader(numChannels, numChannels * bytes, suffix, i_COLOR); for (sampleCounter = 0; sampleCounter < numChannels; ++sampleCounter) { int channel = sampleCounter; if (redBlueSwap && (channel == 0 || channel == 2)) { @@ -239,7 +246,7 @@ uint32_t *createDFDPacked(int bigEndian, int numChannels, uint32_t *DFD = 0; if (numChannels == 6) { /* Special case E5B9G9R9 */ - DFD = writeHeader(numChannels, 4, s_UFLOAT); + DFD = writeHeader(numChannels, 4, s_UFLOAT, i_COLOR); writeSample(DFD, 0, 0, 9, 0, 1, 1, s_UNORM); @@ -292,7 +299,7 @@ uint32_t *createDFDPacked(int bigEndian, int numChannels, } bitOffset += bits[channelCounter]; } - DFD = writeHeader(numSamples, totalBits >> 3, suffix); + DFD = writeHeader(numSamples, totalBits >> 3, suffix, i_COLOR); sampleCounter = 0; for (bitOffset = 0; bitOffset < totalBits;) { @@ -336,7 +343,7 @@ uint32_t *createDFDPacked(int bigEndian, int numChannels, } /* One sample per channel */ - DFD = writeHeader(numChannels, totalBits >> 3, suffix); + DFD = writeHeader(numChannels, totalBits >> 3, suffix, i_COLOR); for (sampleCounter = 0; sampleCounter < numChannels; ++sampleCounter) { writeSample(DFD, sampleCounter, channels[sampleCounter], bits[sampleCounter], bitOffset, @@ -627,7 +634,7 @@ uint32_t *createDFDDepthStencil(int depthBits, /* N.B. Little-endian is assumed. */ uint32_t *DFD = 0; DFD = writeHeader((depthBits > 0) + (stencilBits > 0), - sizeBytes, s_UNORM); + sizeBytes, s_UNORM, i_NON_COLOR); if (depthBits == 32) { writeSample(DFD, 0, KHR_DF_CHANNEL_RGBSDA_DEPTH, 32, 0, diff --git a/lib/dfdutils/makevk2dfd.pl b/lib/dfdutils/makevk2dfd.pl index 3f4df13531..3058be76f0 100755 --- a/lib/dfdutils/makevk2dfd.pl +++ b/lib/dfdutils/makevk2dfd.pl @@ -24,7 +24,10 @@ print "/* SPDX-", "License-Identifier: Apache-2.0 */\n\n"; print "/***************************** Do not edit. *****************************\n"; print " Automatically generated by makevk2dfd.pl.\n"; -print " *************************************************************************/\n"; +print " *************************************************************************/\n\n"; +print "/* Vulkan combined depth & stencil formats are not included here\n"; +print " * because they do not exist outside a Vulkan device.\n"; +print " */\n"; # Loop over each line of input while ($line = <>) { @@ -282,15 +285,6 @@ $foundFormats{$format} = 1; print "case $format: return createDFDDepthStencil(24,0,4);\n"; } - } elsif ($line =~ m/(VK_FORMAT_D32_SFLOAT_S8_UINT)/) { - - # Extract the format identifier from the rest of the line - $format = $1; - if (!exists($foundFormats{$format})) { - # Add the format we've processed to our "done" hash - $foundFormats{$format} = 1; - print "case $format: return createDFDDepthStencil(32,8,5);\n"; - } } elsif ($line =~ m/(VK_FORMAT_D32_SFLOAT)/) { # Extract the format identifier from the rest of the line @@ -309,15 +303,6 @@ $foundFormats{$format} = 1; print "case $format: return createDFDDepthStencil(0,8,1);\n"; } - } elsif ($line =~ m/(VK_FORMAT_D16_UNORM_S8_UINT)/) { - - # Extract the format identifier from the rest of the line - $format = $1; - if (!exists($foundFormats{$format})) { - # Add the format we've processed to our "done" hash - $foundFormats{$format} = 1; - print "case $format: return createDFDDepthStencil(16,8,3);\n"; - } } elsif ($line =~ m/(VK_FORMAT_D16_UNORM)/) { # Extract the format identifier from the rest of the line @@ -327,15 +312,6 @@ $foundFormats{$format} = 1; print "case $format: return createDFDDepthStencil(16,0,2);\n"; } - } elsif ($line =~ m/(VK_FORMAT_D24_UNORM_S8_UINT)/) { - - # Extract the format identifier from the rest of the line - $format = $1; - if (!exists($foundFormats{$format})) { - # Add the format we've processed to our "done" hash - $foundFormats{$format} = 1; - print "case $format: return createDFDDepthStencil(24,8,4);\n"; - } } # ...and continue to the next line diff --git a/lib/dfdutils/vk2dfd.inl b/lib/dfdutils/vk2dfd.inl index e396039928..6f9ef7672b 100644 --- a/lib/dfdutils/vk2dfd.inl +++ b/lib/dfdutils/vk2dfd.inl @@ -4,6 +4,10 @@ /***************************** Do not edit. ***************************** Automatically generated by makevk2dfd.pl. *************************************************************************/ + +/* Vulkan combined depth & stencil formats are not included here + * because they do not exist outside a Vulkan device. + */ case VK_FORMAT_R4G4_UNORM_PACK8: { int channels[] = {1,0}; int bits[] = {4,4}; return createDFDPacked(0, 2, bits, channels, s_UNORM); @@ -218,9 +222,6 @@ case VK_FORMAT_D16_UNORM: return createDFDDepthStencil(16,0,2); case VK_FORMAT_X8_D24_UNORM_PACK32: return createDFDDepthStencil(24,0,4); case VK_FORMAT_D32_SFLOAT: return createDFDDepthStencil(32,0,4); case VK_FORMAT_S8_UINT: return createDFDDepthStencil(0,8,1); -case VK_FORMAT_D16_UNORM_S8_UINT: return createDFDDepthStencil(16,8,3); -case VK_FORMAT_D24_UNORM_S8_UINT: return createDFDDepthStencil(24,8,4); -case VK_FORMAT_D32_SFLOAT_S8_UINT: return createDFDDepthStencil(32,8,5); case VK_FORMAT_BC1_RGB_UNORM_BLOCK: return createDFDCompressed(c_BC1_RGB, 4, 4, 1, s_UNORM); case VK_FORMAT_BC1_RGB_SRGB_BLOCK: return createDFDCompressed(c_BC1_RGB, 4, 4, 1, s_SRGB); case VK_FORMAT_BC1_RGBA_UNORM_BLOCK: return createDFDCompressed(c_BC1_RGBA, 4, 4, 1, s_UNORM); diff --git a/lib/internalexport.def b/lib/internalexport.def index 33cc1399cc..5b22dff647 100644 --- a/lib/internalexport.def +++ b/lib/internalexport.def @@ -18,9 +18,10 @@ EXPORTS ?get_image_level_info@basisu_transcoder@basist@@QEBA_NPEBXIAEAUbasisu_image_level_info@2@II@Z ?start_transcoding@basisu_transcoder@basist@@QEAA_NPEBXI@Z ?transcode_image_level@basisu_transcoder@basist@@QEBA_NPEBXIIIPEAXIW4transcoder_texture_format@2@IIPEAUbasisu_transcoder_state@2@I@Z + createDFDCompressed + createDFDDepthStencil createDFDUnpacked createDFDPacked - createDFDCompressed findMapping interpretDFD isProhibitedFormat diff --git a/lib/internalexport_mingw.def b/lib/internalexport_mingw.def index 0406959794..1a61a2bc89 100644 --- a/lib/internalexport_mingw.def +++ b/lib/internalexport_mingw.def @@ -18,9 +18,10 @@ EXPORTS _ZNK6basist17basisu_transcoder20get_image_level_infoEPKvjRNS_23basisu_image_level_infoEjj _ZN6basist17basisu_transcoder17start_transcodingEPKvj _ZNK6basist17basisu_transcoder21transcode_image_levelEPKvjjjPvjNS_25transcoder_texture_formatEjjPNS_23basisu_transcoder_stateEj + createDFDCompressed + createDFDDepthStencil createDFDUnpacked createDFDPacked - createDFDCompressed findMapping interpretDFD isProhibitedFormat diff --git a/lib/texture2.c b/lib/texture2.c index 7987b9cc75..f9bbfcb95c 100644 --- a/lib/texture2.c +++ b/lib/texture2.c @@ -310,6 +310,37 @@ ktxFormatSize_initFromDfd(ktxFormatSize* This, ktx_uint32_t* pDfd) return true; } +/** + * @private + * @~English + * @brief Create a DFD for a VkFormat. + * + * This KTX-specific function adds support for combined depth stencil formats + * which are not supported by @e dfdutils' @c vk2dfd function because they + * are not seen outside a Vulkan device. KTX has its own definitions for + * these that enable uploading, with some effort. + * + * @param[in] vkFormat the format for which to create a DFD. + */ +static uint32_t* +ktxVk2dfd(ktx_uint32_t vkFormat) +{ + switch(vkFormat) { + case VK_FORMAT_D16_UNORM_S8_UINT: + // 2 16-bit words. D16 in the first. S8 in the 8 LSBs of the second. + return createDFDDepthStencil(16, 8, 4); + case VK_FORMAT_D24_UNORM_S8_UINT: + // 1 32-bit word. D24 in the MSBs. S8 in the LSBs. + return createDFDDepthStencil(24, 8, 4); + case VK_FORMAT_D32_SFLOAT_S8_UINT: + // 2 32-bit words. D32 float in the first word. S8 in LSBs of the + // second. + return createDFDDepthStencil(32, 8, 8); + default: + return vk2dfd(vkFormat); + } +} + /** * @memberof ktxTexture2 @private * @~English @@ -370,9 +401,10 @@ ktxTexture2_construct(ktxTexture2* This, ktxTextureCreateInfo* createInfo, memset(This, 0, sizeof(*This)); if (createInfo->vkFormat != VK_FORMAT_UNDEFINED) { - This->pDfd = vk2dfd(createInfo->vkFormat); + This->pDfd = ktxVk2dfd(createInfo->vkFormat); if (!This->pDfd) return KTX_INVALID_VALUE; // Format is unknown or unsupported. + #ifdef _DEBUG // If this fires, an unsupported format or incorrect DFD // has crept into vk2dfd. @@ -1528,10 +1560,8 @@ lcm4(uint32_t a) ktx_uint32_t alignment; if (This->supercompressionScheme != KTX_SS_NONE) alignment = 1; - else if (This->vkFormat != VK_FORMAT_UNDEFINED) - alignment = lcm4(This->_protected->_formatSize.blockSizeInBits / 8); else - alignment = 16; + alignment = lcm4(This->_protected->_formatSize.blockSizeInBits / 8); return alignment; }