GPUOpen-Tools / compressonator

Tool suite for Texture and 3D Model Compression, Optimization and Analysis using CPUs, GPUs and APUs
1.3k stars 196 forks source link

ETC codecs swap red and blue channels #247

Closed carlschissler closed 8 months ago

carlschissler commented 1 year ago

The channel ordering behavior of the ETC1 and ETC2 compression codecs is inconsistent with the other formats. I have test images (from another source) that when decompressed using compressonator have red and blue channels swapped. The same behavior is observed when compressing to ETC formats using compressonator.

The reason for this is that the ETC codecs seem to always swizzle the data using the SWIZZLE_DWORD() macro, but don't undo the swizzle afterwards. I was able to fix this issue by swizzling a second time (by swapping red and blue when the data is read/written to the input/output channels).

Lucodivo commented 1 year ago

I have noticed this problem as well. But it only happened when using the Compressinator SDK. I could not reproduce it using Compressinator GUI.

Lucodivo commented 1 year ago

I just ran the following CLI command and it does NOT have this issue. The red and blue channels are in the correct positions after compression.

.\compressonatorcli.exe -fd ETC2_RGBA -fx BMP example.jpg example.bmp

So the GUI and CLI do NOT have this issue but the SDK does. That's most likely pretty good news.

carlschissler commented 1 year ago

I think the CLI does some changes to the input data to make it in the channel format expected by the library, which is BGRA if I recall. So, that would explain why the CLI works but the library has swapped red and blue when channels are passed in RGBA order. Basically the library is inconsistent with how it expects the input channels to be arranged, and CLI covers up that inconsistency by doing "the right thing" to make it work. However, none of this is documented and the library code is broken if you expect to pass in usual RGBA ordered channels. You can pass in CMP_FORMAT_RGBA_8888 as the format, but the library ignores it and always assumes it's BGRA order and does incorrect swizzling.

In my experience, the library seems to be almost untested, since I found several bugs of similar nature. It seems like AMD does not have any tests at all for the C++ API and only tests the code via the CLI, which allows bugs of this type to lurk for a long time.

Lucodivo commented 1 year ago

Apologies, I'm fairly new to thinking about compression. I realized that my test cases were severely flawed.

When I tested the GUI, I trusted the GUI's own viewer to be an accurate showing on whether or not it was swapping Red/Blue.

When I tested the CLI, I issued a command that compressed to ETC2_RGBA but then saved to a .bmp file format. Which, logically, makes absolutely no sense. BMP files obviously do not support ETC2 compression.

They apparently do have tests here in the repo for the CLI. Which includes ETC2_RGB, ETC2_RGBA, and the other variants. But, as far as I can tell, the tests just make sure there is no errors. Which is weird, because the GUI already has a diff tool built into it. Seems like the repository could have pre-baked compression images and use the diff tool to verify the test results are equal the pre-baked compressed images. Might bloat the project with so many separate compression formats with their different mipmap levels and compression quality. But this project is already ~1GB so not sure it would make much of a difference.

At this point in time, I don't have any trustworthy ways to properly render KTX/DDS images from the GUI/CLI. As I was using the SDK to bake file formats of my own.

For quick testing, I used the project kopaka1822/ImageView. I don't know much about this project, so I can't attest whether or not they also do weird swizzling. But if this project can be trusted when viewing ETC2 encoded images, I can confirm that both the GUI and CLI are, in fact, both broken in the same way. From what I can tell, red & blue channels are always incorrectly swapped when encoding ETC2_RGB & ETC2_RGBA. Regardless of CLI, GUI, or SDK.

Apologies for the false info from before.

denislevesqueAMD commented 1 year ago

@carlschissler @Lucodivo I believe this is the same issue as reported in #199 and #144 and was due to using the incorrect macros in the ETC codecs. It should be fixed in next release.

NavNTCMP commented 8 months ago

@Lucodivo Issue addressed in v4.5 release