I am trying to convert .dds textures from the Bistro scene to KTX/KTX2 format for use with Vulkan.
Using the GUI version of NVTT Exporter, I can successfully convert the files. The generated KTX files pass ktx validate without errors and load correctly with the KTX library.
However, when I use the command-line interface:
nvtt_export hoo.dds -o hoo.ktx
the resulting KTX files do not work properly. Although ktx validate reports no errors, loading them with the KTX library fails.
Environment:
NVIDIA Texture Tools Exporter 2024.1.1
KTX tools v4.4.2
Is there any difference in default settings between the GUI and CLI versions that could explain this behavior?
Could you try exporting to a file with the .ktx2 extension instead of .ktx, like this?
nvtt_export hoo.dds -o hoo.ktx2
nvtt_export doesn’t support exporting KTX version 1 files (.ktx), so when it sees that extension it instead exports its default, which is the DDS format. As a result, if you open hoo.ktx in a hex editor, you’ll probably see it start with the characters DDS , which is the signature for a DDS file. (This is a bit confusing; perhaps we should have nvtt_export print a warning when this happens.)
I tried exporting with the .ktx2 extension using the CLI command you suggested:
nvtt_export hoo.dds -o hoo.ktx2
This does produce a file whose header contains the ktx 20 signature, so it appears that a KTX2 file is being generated.
However, the behavior differs from the KTX2 file generated by the GUI when running ktx validate.
For the file created via the GUI, I get the following output:
ktx validate .\Antenna_Metal_BaseColor_by_GUI.ktx2
Validation successful
warning-6030: Deprecated unsized bytesPlanes in basic DFD block. Since specification 2.0.4 bytesPlanes must be sized (non-zero) for supercompressed textures.
DFD block #1 bytesPlanes0 in basic DFD block is 0 but for KTX_SS_ZSTD supercompressed textures, since specification 2.0.4, it must be non-zero.
However, for the file created via the CLI, ktx validate produces no output at all—there is neither an error message nor a success message.
I also compared the header sections of the files generated by the GUI and CLI and observed differences between them.
It seems that the CLI-generated file may be missing something expected by ktx validate, but I am not sure what the exact cause is.
here is header of ktx2 made by CLI q0tUWCAyMLsNChoKkgAAAAEAAAAACAAAAAgAAAAAAAAAAAAAAQAAAAwAAAAAAAAAcAEAACwAAACcAQAARAAAAAAAAAAAAAAAAAAAAAAAAABQVxUAAAAAAAAAQAAAAAAAAABAAAAAAABQVwUAAAAAAAAAEAAAAAAAAAAQAAAAAABQVwEAAAAAAAAABAAAAAAAAAAEAAAAAABQVwAAAAAAAAAAAQAAAAAAAAABAAAAAABQFwAAAAAAAABAAAAAAAAAAEAAAAAAAABQBwAAAAAAAAAQAAAAAAAAABAAAAAAAABQAwAAAAAAAAAEAAAAAAAAAAQAAAAAAABQAgAAAAAAAAABAAAAAAAAAAEAAAAAAAAQAgAAAAAAAEAAAAAAAAAAQAAAAAAAAAAAAgAAAAAAABAAAAAAAAAAEAAAAAAAAADwAQAAAAAAABAAAAAAAAAAEAAAAAAAAADgAQAAAAAAABAAAAAAAAAAEAAAAAAAAAAsAAAAAAAAAAIAKACGAQIAAwMAABAAAAAAAAAAAAB/AAAAAAAAAAAA/////xAAAABLVFhzd2l6emxlAHJnYmEAKgAAAEtUWHdyaXRlcgBudnByby1zYW1wbGVzJyBudl9rdHggdmVyc2lvbiAxAAAA
and this is by GUI q0tUWCAyMLsNChoKkgAAAAEAAAAACAAAAAgAAAAAAAAAAAAAAQAAAAwAAAAAAAAAcAEAACwAAACcAQAARAAAAAAAAAAAAAAAAAAAAAAAAABQVxUAAAAAAAAAQAAAAAAAAABAAAAAAABQVwUAAAAAAAAAEAAAAAAAAAAQAAAAAABQVwEAAAAAAAAABAAAAAAAAAAEAAAAAABQVwAAAAAAAAAAAQAAAAAAAAABAAAAAABQFwAAAAAAAABAAAAAAAAAAEAAAAAAAABQBwAAAAAAAAAQAAAAAAAAABAAAAAAAABQAwAAAAAAAAAEAAAAAAAAAAQAAAAAAABQAgAAAAAAAAABAAAAAAAAAAEAAAAAAAAQAgAAAAAAAEAAAAAAAAAAQAAAAAAAAAAAAgAAAAAAABAAAAAAAAAAEAAAAAAAAADwAQAAAAAAABAAAAAAAAAAEAAAAAAAAADgAQAAAAAAABAAAAAAAAAAEAAAAAAAAAAsAAAAAAAAAAIAKACGAQIAAwMAABAAAAAAAAAAAAB/AAAAAAAAAAAA/////xAAAABLVFhzd2l6emxlAHJnYmEAKgAAAEtUWHdyaXRlcgBudnByby1zYW1wbGVzJyBudl9rdHggdmVyc2lvbiAxAAAA
That’s interesting! I think ktx validate is correct for the file created via the GUI, so thank you for pointing that out – NVTTE 2024’s KTX writer was based on the pre-2.0.4 KTX2 specification, so it is indeed writing 0 for bytesPlanes there (here’s the part of the source code that does that)! I’ll see if I can fix that.
I bet then the difference is that the GUI applies Zstandard supercompression by default, while the CLI doesn’t. So ktx validate probably succeeds on the CLI-generated .ktx2 file, but doesn’t print a message – and if you run echo %errorlevel% afterwards, it’ll probably print 0 (i.e. ktx validate didn’t crash, and instead exited with a success code). I forget why the CLI doesn’t apply Zstandard supercompression by default, but it could be because there’s no --no-zcmpoption to turn supercompression off, only a --zcmp option to turn it on.
So, if you run nvtt_export hoo.dds --zcmp 5 -o hoo.ktx2, then (hopefully) you should get identical files, and both should produce the same ktx validate message.