Skip to content

Add dds to ktx2 lossless converter#1223

Open
walcht wants to merge 9 commits into
KhronosGroup:mainfrom
walcht:add-dds-to-ktx2-lossless-converter
Open

Add dds to ktx2 lossless converter#1223
walcht wants to merge 9 commits into
KhronosGroup:mainfrom
walcht:add-dds-to-ktx2-lossless-converter

Conversation

@walcht

@walcht walcht commented Jul 23, 2026

Copy link
Copy Markdown
Contributor

Fixes #92.

Still in draft because testing isn't yet done (a bit difficult since I have to use my other BCn PR to test extracts) => is now ready for review (still a couple of missing edge-case test files and invalid dds test files).

Feel free to give an early review but this is still far from done.

walcht added 3 commits July 23, 2026 14:13
Signed-off-by: Walid Chtioui <walid.chtioui.main@gmail.com>
…t/KTX-Software into add-dds-to-ktx2-lossless-converter
Signed-off-by: Walid Chtioui <walid.chtioui.main@gmail.com>
walcht added 2 commits July 24, 2026 02:47
Signed-off-by: Walid Chtioui <walid.chtioui.main@gmail.com>
…ings

Signed-off-by: Walid Chtioui <walid.chtioui.main@gmail.com>

@MarkCallow MarkCallow left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is exciting. A DDS converter has been on our To Do list for a long time.

This together with your BCn codec and the format queries I mention in one of my comments will make a very nice addition to KTX-Software.

Looks good to me.

Comment thread tools/ktx/command_convert.cpp
Comment thread tools/ktx/command_convert.cpp
Comment thread tools/ktx/command_convert.cpp Outdated
@walcht

walcht commented Jul 24, 2026

Copy link
Copy Markdown
Contributor Author

Does DDS use KTX_GL_UNPACK_ALIGNMENT?

I suspect you copied a comment from the KTX code that refers to handling for KTX v1 data. KTX v2 uncompressed images are always tightly packed.

It doesn't. I just left the comment there so that I verify if there is anything I have to worry about in terms of alignment. Good to know that KTX v2 is always tightly packed (less things to worry about).

I would like generate the reverse mapping from this data to use here but it requires Ruby coding which I am not very familiar with. It should be done from the database because then it is guaranteed spec. compliant.

I will try to figure this out. Ruby should be fairly simple to pick up, I'll open a PR in KTX-Specification if I manage to generate the enum.

What formats are not supported?

I left them commented out. Examples:

//  case TDDS_AYUV: return VK_FORMAT_UNDEFINED;
//  case TDDS_Y410: return VK_FORMAT_UNDEFINED;
//  case TDDS_Y416: return VK_FORMAT_UNDEFINED;
//  case TDDS_NV12: return VK_FORMAT_UNDEFINED;
//  case TDDS_P010: return VK_FORMAT_UNDEFINED;
//  case TDDS_P016: return VK_FORMAT_UNDEFINED;
//  case TDDS_420_OPAQUE: return VK_FORMAT_UNDEFINED;
//  case TDDS_YUY2: return VK_FORMAT_UNDEFINED;
//  case TDDS_Y210: return VK_FORMAT_UNDEFINED;
//  case TDDS_Y216: return VK_FORMAT_UNDEFINED;
//  case TDDS_NV11: return VK_FORMAT_UNDEFINED;
//  case TDDS_AI44: return VK_FORMAT_UNDEFINED;
//  case TDDS_IA44: return VK_FORMAT_UNDEFINED;
//  case TDDS_P8: return VK_FORMAT_UNDEFINED;
//  case TDDS_A8P8: return VK_FORMAT_UNDEFINED;

// ...

//  case TDDS_R16_UNORM_X8_TYPELESS: return VK_FORMAT_UNDEFINED;
//  case TDDS_X16_TYPELESS_G8_UINT: return VK_FORMAT_UNDEFINED;
//  case TDDS_P208: return VK_FORMAT_UNDEFINED;
//  case TDDS_V208: return VK_FORMAT_UNDEFINED;
//  case TDDS_V408: return VK_FORMAT_UNDEFINED;
//  case TDDS_R10G10B10_SNORM_A2_UNORM: return VK_FORMAT_UNDEFINED;
//  case TDDS_R4G4_UNORM: return VK_FORMAT_UNDEFINED;
//  case TDDS_G4R4_UNORM: return VK_FORMAT_UNDEFINED;
//  case TDDS_A4B4G4R4_UNORM: return VK_FORMAT_UNDEFINED;
//  case TDDS_X4B4G4R4_UNORM: return VK_FORMAT_UNDEFINED;
//  case TDDS_A4R4G4B4_UNORM: return VK_FORMAT_UNDEFINED;
//  case TDDS_X4R4G4B4_UNORM: return VK_FORMAT_UNDEFINED;
//  case TDDS_B4G4R4X4_UNORM: return VK_FORMAT_UNDEFINED;
//  case TDDS_R4G4B4A4_UNORM: return VK_FORMAT_UNDEFINED;
//  case TDDS_R4G4B4X4_UNORM: return VK_FORMAT_UNDEFINED;
//  case TDDS_B5G5R5X1_UNORM: return VK_FORMAT_UNDEFINED;
//  case TDDS_R5G5B5A1_UNORM: return VK_FORMAT_UNDEFINED;
//  case TDDS_R5G5B5X1_UNORM: return VK_FORMAT_UNDEFINED;
//  case TDDS_A1R5G5B5_UNORM: return VK_FORMAT_UNDEFINED;
//  case TDDS_X1R5G5B5_UNORM: return VK_FORMAT_UNDEFINED;
//  case TDDS_A1B5G5R5_UNORM: return VK_FORMAT_UNDEFINED;
//  case TDDS_X1B5G5R5_UNORM: return VK_FORMAT_UNDEFINED;
//  case TDDS_R5G6B5_UNORM: return VK_FORMAT_UNDEFINED;
//  case TDDS_B2G3R3_UNORM: return VK_FORMAT_UNDEFINED;
//  case TDDS_B2G3R3A8_UNORM: return VK_FORMAT_UNDEFINED;
//  case TDDS_G8R8_UNORM: return VK_FORMAT_UNDEFINED;
//  case TDDS_G8R8_SNORM: return VK_FORMAT_UNDEFINED;

I don't know what the X stands for in these formats. I also have no idea what the first formats are (e.g., AYUV).

@MarkCallow

Copy link
Copy Markdown
Collaborator

I don't know what the X stands for in these formats. I also have no idea what the first formats are (e.g., AYUV).

In Vulkan formats X means unused a.k.a. padding bits. AYUV is almost certainly a YUV format with alpha.

That database I mentioned is to DXGI formats. I do not know if those and DDS formats are equivalent or use the same enumeration values.

@walcht

walcht commented Jul 24, 2026

Copy link
Copy Markdown
Contributor Author

I will try to figure this out. Ruby should be fairly simple to pick up, I'll open a PR in KTX-Specification if I manage to generate the enum.

I couldn't get my head around Ruby so I re-wrote the Ruby scripts in Python. I will open a PR feel free to accept it or close it (at least some Python equivalents can be referred to in PR search).

I'm finalizing the testsuite (there are quite a lot of combinations to test). There are also some issues with tinydds.h with regards to arrays/volumes/cubemap arrays (which apparently are supported). I will add another comment about these later.

<dt>-t, \--input-type &lt;type&gt;</dt>
<dd>Type of input file. Currently @b type must be @c ktx. Case insensitive.</dd>
<dd>Type of input file. Currently @b type must be either @c ktx or @c dds. Case insensitive.</dd>
<dt>-d, \--drop-bad-orientation</dt>

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add a note that this is ignored if the input type is not ktx and make sure the implementation follows the note.

@MarkCallow

MarkCallow commented Jul 24, 2026

Copy link
Copy Markdown
Collaborator

I couldn't get my head around Ruby so I re-wrote the Ruby scripts in Python. I will open a PR feel free to accept it or close it (at least some Python equivalents can be referred to in PR search).

We want to keep everything in the spec. repo. Ruby, which we need for Asciidoctor, in order to minimize dependencies so I won't accept the PR. Could the Python version of the DXGI to VkFormat generator you created be useful for working on a Ruby version?

What is the answer to my TDDS vs DXGI question?

@walcht

walcht commented Jul 24, 2026

Copy link
Copy Markdown
Contributor Author

Could the Python version of the DXGI to VkFormat generator you created be useful for working on a Ruby version?

I will try to translate it and open it as a PR in Ruby but I have never programmed in it before.

What is the answer to my TDDS vs DXGI question?

Ah, I forgot to answer. They are the same (as far as I see they map one-to-one). So once we generate DXGI -> VkFormat the TinyDDS -> VkFormat is trivial. More details:

TinyDDS_Format tinydds_format = TinyDDS_GetFormat(handle); // returns format in this TinyDDS-specific struct `TinyDDS_Format`
if (tinydds_format < TDDS_SYNTHESISED_DXGIFORMATS) {
   DXGI_FORMAT dxgi_format = static_cast<DXGI_FORMAT>(tinydds_format);  // they map 1-to-1
} else {
   // unsupported format (see comment below)
}

The formats that cannot be translated from TinyDDS to DXGI_FORMAT are these:

TDDS_G4R4_UNORM = TDDS_SYNTHESISED_DXGIFORMATS,
TDDS_A4B4G4R4_UNORM,
TDDS_X4B4G4R4_UNORM,
TDDS_A4R4G4B4_UNORM,
TDDS_X4R4G4B4_UNORM,
TDDS_B4G4R4X4_UNORM,
TDDS_R4G4B4A4_UNORM,
TDDS_R4G4B4X4_UNORM,
TDDS_B5G5R5X1_UNORM,
TDDS_R5G5B5A1_UNORM,
TDDS_R5G5B5X1_UNORM,
TDDS_A1R5G5B5_UNORM,
TDDS_X1R5G5B5_UNORM,
TDDS_A1B5G5R5_UNORM,
TDDS_X1B5G5R5_UNORM,
TDDS_R5G6B5_UNORM,
TDDS_B2G3R3_UNORM,
TDDS_B2G3R3A8_UNORM,
TDDS_G8R8_UNORM,
TDDS_G8R8_SNORM,
TDDS_R8G8B8_UNORM,
TDDS_B8G8R8_UNORM,
TDDS_A8B8G8R8_SNORM,
TDDS_B8G8R8A8_SNORM,
TDDS_R8G8B8X8_UNORM,
TDDS_B8G8R8X8_UNORM,
TDDS_A8B8G8R8_UNORM,
TDDS_X8B8G8R8_UNORM,
TDDS_A8R8G8B8_UNORM,
TDDS_X8R8G8B8_UNORM,
TDDS_R10G10B10A2_SNORM,
TDDS_B10G10R10A2_UNORM,
TDDS_B10G10R10A2_SNORM,
TDDS_A2B10G10R10_UNORM,
TDDS_A2B10G10R10_SNORM,
TDDS_A2R10G10B10_UNORM,
TDDS_A2R10G10B10_SNORM,
TDDS_G16R16_UNORM,
TDDS_G16R16_SNORM,

@walcht

walcht commented Jul 24, 2026

Copy link
Copy Markdown
Contributor Author

Add a note that this is ignored if the input type is not ktx and make sure the implementation follows the note.

There is this comment already that addresses it, no? Ignored unless @b type is @c ktx.
I verified the implementation and this option is only used in convertKtx function.

Signed-off-by: Walid Chtioui <walid.chtioui.main@gmail.com>
walcht added 3 commits July 24, 2026 14:00
Signed-off-by: Walid Chtioui <walid.chtioui.main@gmail.com>
Signed-off-by: Walid Chtioui <walid.chtioui.main@gmail.com>
Signed-off-by: Walid Chtioui <walid.chtioui.main@gmail.com>
@walcht
walcht marked this pull request as ready for review July 24, 2026 12:14
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Fully support DDS to KTX2 pipeline

2 participants