microsoft / DirectXTex

DirectXTex texture processing library
https://walbourn.github.io/directxtex/
MIT License
1.82k stars 447 forks source link

Can't load some nvidia-texture-tool dds files #56

Closed MLPMil closed 7 years ago

MLPMil commented 7 years ago

Hello again, is DirectXTex required to support 3rd party texture toolsets?

I got an issue loading a dds created through nvidia-texture-tool (the one referenced in your wiki): see attached test.dds sample.

Specifically, such tool defines (and uses) a couple of custom pixelformat flags (DDPF_NORMAL and DDPF_SRGB) that "breaks" GetDXGIFormat implementation in DirectXTexDDS.cpp.

The nvidia-texture-tool flags are declared here: https://github.com/castano/nvidia-texture-tools/blob/8d333f2a4f4b223e569f4f6e65a71a9886f4edf1/src/nvimage/DirectDrawSurface.h#L56 Sample commandline: nvcompress.exe -bc1 -normal -nomips test.tga test.dds

Maybe an optional (or hardcoded) mask could be applied to remove those and other unwanted pixelformat bits before parsing dds header. Or maybe a "dds recovery mode" could be implemented according to reserved fields value (if reserved field == NVTT, then remove NVTT bits).

Note that the attached file can be successfully loaded by VS2012, VS2013, VS2015, DirectXTK(12) and DDSTextureLoader(12), whereas latest DDSView can't open it. DirectXTex was able to load it till 98343c572f9bdb20e0471d18a26ede0b7d0c5a63 commit.

Best regards mlpmil

test.zip

walbourn commented 7 years ago

Thanks for the information. If they were going to take ownership of the reserved field, they probably should have use one of them for their extra flags :)

I'll take a look at the best solution Checking the reserved field for their tag and then mask the extra flags seems reasonable. Any idea what DDPF_NORMAL and DDPF_SRGB are supposed to indicate? I'm guessing they are trying to capture DXGI formats without using the new DX10 header...

walbourn commented 7 years ago

Ok, I now ignore these flags on read so you get a proper format match. If it's an NVTT with DDPF_SRGB, I return the MakeSRGB of the format.

Fixed in this commit

MLPMil commented 7 years ago

Thank you for the quick fix! I agree with you about using reserved fields for custom flags :)

Looking at nvidia-texture-tools code, DDPF_SRGB is used in conjunction with DX10 SRGB formats and it's set, but unused, whereas DDPF_NORMAL flags textures where source image was declared as normalmap. If DDPF_NORMAL is present in dds header, it's also used to rebuild normals when loading bc3_unorm, ati2 and bc5_unorm formats; for all other formats, it's set but not used: I think that this additional conversion is not required here (it could be done in shaders if needed).

Regards

walbourn commented 7 years ago

Fix included in the July 2017 release