Decode BC6 texture data?

Started by
9 comments, last by Vilem Otte 7 months ago

Does anyone have code to convert BC6H texture data to 32-bit RGBA? I know there are a couple of libraries out there but they are rather bloated for my purposes, and I just want one simple function that decodes a BC6 block or image.

10x Faster Performance for VR: www.ultraengine.com

Advertisement

I've used AMD's compressonator library. It does the job, but is kind of janky. I found like a dozen bugs when integrating it into my engine. You can use it convert images with 1 function: CMP_ConvertTexture(). It also does a bunch of other formats.

Why are you wanting to decode BC6H? I'd imagine you'd want to use it for rendering directly. You will lose precision by converting to 32-bit RGBA, since BC6H has half float storage. FYI BC6H has no alpha channel, it's float16 HDR RGB data only AFAIK.

If you don't want the library bloat, maybe you can make use of the code in this file. It's not a trivial format, you probably won't find a small simple decoder.

LOL I was looking through the open issues for Compressonator and I see that there is still one open that I opened several months ago: Encoding/decoding BC6H is impossible due to lack of RGB-16F buffer type

it's actually impossible to decode BC6H with the library as-is because it doesn't provide the 16-bit float interface to the image data. I had to significantly modify the code to add this capability.

For examples of the insane level of the jank in the library, here are other issues I opened, all after basic usage of the library in my engine/editor. Many of the formats were completely broken.
BC5 / ATI2N codec missing red channel with CCodecBuffer_RG8
ETC codecs swap red and blue channels #247
CMP_Feedback_Proc is useless without user data pointer(s)
Swizzle issues

These are just the issues that are still open. There were several more that have been resolved. I also improved the DXT compression performance by 28% by just changing calls to std::floor() to _mm_floor_ss().

This library has been around since at least 2006. I can't believe there were so many issues. It seems like AMD has not done any direct testing whatsoever of the C++ library. They seem to only test it via the command line utility, which obscures many of the bugs related to swizzling.

I need this primarily for displaying thumbnails for textures in a GUI that uses GDI for drawing. I have decoders for every other format the engine supports.

10x Faster Performance for VR: www.ultraengine.com

I've written my own encoder and decoder (decoder is more complex, in encoder - I tried all modes, but dropped most of those as they didn't seem “good enough” for me and doing all of those ended up taking a lot of computation time). One of the references is here:

https://github.com/iOrange/bcdec/blob/main/bcdec.h

Aressera said:
This library has been around since at least 2006. I can't believe there were so many issues. It seems like AMD has not done any direct testing whatsoever of the C++ library. They seem to only test it via the command line utility, which obscures many of the bugs related to swizzling.

I do remember it, but I think there is a new one around for quite some time and The Compressonator was abandoned. I eventually just rolled all BC compression/decompression code on my own. There is enough information with specs and some sample implementations to do that within reasonable time frame. Makes building projects from engine to runtime a lot more straight forward and doesn't require on 3rd party.

My current blog on programming, linux and stuff - http://gameprogrammerdiary.blogspot.com

Vilem Otte said:
I eventually just rolled all BC compression/decompression code on my own. There is enough information with specs and some sample implementations to do that within reasonable time frame. Makes building projects from engine to runtime a lot more straight forward and doesn't require on 3rd party.

I would have done that but I don't have the time to write my own implementation for all the different formats. There are other more important matters. However, I see some potential advantages of DIY. Compressonator is fairly slow at BCn compression (roughly 0.5 Mpx per second per thread, it takes 8 seconds to compress a 2048px texture) while the fastest benchmarks I've seen are in the 40-80 Mpx/s/thread range. From looking at the bad state of the compressonator code, I see lots of opportunities to speed it up with SIMD. It's mostly manipulating individual bytes, which is colossally slow compared to AVX512.

@Vilem Otte Thank you, that looks like it is probably what I am looking for.

I spent about 30 minutes on the compressonator code, but you end up including so many headers that you might as well build the whole project.

10x Faster Performance for VR: www.ultraengine.com

Aressera said:
I would have done that but I don't have the time to write my own implementation for all the different formats.

It really depends on what you need that for. I originally used The Compressonator (but that was quite long time back) and for pre-processing textures it was fine. I hit the wall though at the point where I wanted to do compression in runtime to some extent (and further when I implemented virtual textures - which I wanted to have BC compressed). Having your own toolbox for that makes things a little bit more comfortable.

My implementation is CPU-side only now (while GPU compression might be faster - I can simply offload it on another thread and do it in the background). It is good enough for its purpose, sadly I never went in to benchmark it - so I can't compare it.

My current blog on programming, linux and stuff - http://gameprogrammerdiary.blogspot.com

I implemented the bcdec library and it works great. Thanks for pointing it out.

I don't know why that lib does not appear in Github search results:

https://github.com/search?q=bc6h&type=repositories

10x Faster Performance for VR: www.ultraengine.com

Good job!

Whenever I searched for BC6H/BC7 information - there are often only format specifications, decoding specifications (more common) and tools. Finding actual implementations is … well … somewhat challenging.

Building encoder/decoder based solely on specification is quite a challenging task (the specifications could be a LOT easier to find and a somewhat more readable in description).

My current blog on programming, linux and stuff - http://gameprogrammerdiary.blogspot.com

This topic is closed to new replies.

Advertisement