Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support for DDS S3TC BC4 to BC7 compression formats #2338

Closed
Silverlan opened this issue Sep 9, 2019 · 7 comments
Closed

Support for DDS S3TC BC4 to BC7 compression formats #2338

Silverlan opened this issue Sep 9, 2019 · 7 comments

Comments

@Silverlan
Copy link

Silverlan commented Sep 9, 2019

It looks like oiio currently only supports DXT1 to DXT5, but not any of the newer ones (i.e. BC4, BC5, BC6 and BC7). While I'm not sure how commonly used BC4, BC5 and BC7 are, BC6 is the only one of the bunch which properly supports HDR colors. BC5 is great for normal maps, but DXT5n can be used as an alternative for now.

The same support would be nice for the KTX format as well, if that does get added.

The GLI library has support for all of these and could be handy as a reference.

@lgritz
Copy link
Collaborator

lgritz commented Jan 3, 2020

Partial Update:

PR #2451 proposes a patch that lets us use an external libsquish for DDS compression, if found. Current libsquish is v1.15, versus the embedded version we've had since 2010 which is v1.10 + some backported code from 1.13 (or so I'm told).

libsquish 1.14 added support for BC4 & BC5.

So a possible path forward here would include:

  • Updating our embedded libsquish to 1.15, or alternately, remove the embedded version and rely entirely on the external one, as we do for several other formats.
  • Then modifying our dds reading code to use the new BC4/5 decoding that is provided by newer editions of libsquish.

@jessey-git
Copy link
Contributor

Just ran into this today myself when trying to explore the various ORCA asset repositories here:

Most of the normal map textures in both of those archives are stored in BC5/ATI2 format. This makes exploring them quite cumbersome as renderers making direct use of OIIO fail to load the assets.

iinfo ERROR: "G:\performance\zero_day\MEASURE_SEVEN\tex\room_Normal.dds" : Unsupported compression type

@aras-p
Copy link
Contributor

aras-p commented Jun 15, 2022

"Reading" and "Writing" perhaps should be considered as separate tasks. The former one is enormously easier than the latter -- code required to read/decompress BCn formats (including BC6H/BC7) is fairly small and can be made decently fast. Code required to write/compress BC6H & BC7 is massive in comparison.

@aras-p
Copy link
Contributor

aras-p commented Jun 28, 2022

I'd like to take on this issue, but first would be good to have opinions whether my approach makes sense (cc @lgritz?).

DDS in OIIO today only supports reading the files, not writing them. So embedding/using whole of libsquish just to read the files sounds like an overkill. Plus, libsquish is probably a "dead" project by now, even upgrading it to latest version would not solve the BC4/BC5 issues -- latest libsquish (1.15) adds support for compressing BC4/BC5, but decompression (i.e. "reading") them does not work there.

My plan would be like:

  1. Extend oiio dds test suite coverage. Today it only contains 1 image (dxt1/bc1 format), I'd add all the bc1..bc7 formats, plus several uncompressed ones, some with mipmaps as well. This can be done without any changes to oiio code itself; add new images into the test images repository, then extend the testsuite/dds/run.py to test the new images.
  2. Replace usage of libsquish with bcdec (https://github.com/iOrange/bcdec) - in my tests (see blog post), it's both faster than libsquish (3x faster at bc1/dxt1 decoding, 2x faster at bc3/dxt5 decoding), but also supports all the BCn formats, and is trivial to build (just one source file). It's "unlicense" aka public domain code. A good question would be, whether to embed it directly into source code (replacing currently embedded libsquish), or whether to pull it from github dynamically similar to how it's done for fmtlib.
  3. Now oiio would get: 1) for already supported formats like bc1/dxt1 or bc3/dxt5, loading them would be faster, and 2) it would also get support for loading bc4, bc5, bc6h (hdr), bc7 formats.

Opinions on the above?

@lgritz
Copy link
Collaborator

lgritz commented Jul 2, 2022

Hi, sorry for the delay @aras-p .

Heck yeah, I'd be thrilled to see you tackle this.

I have no particular attachment to libsquish. It's just what the student who wrote the dds support used when he added this functionality ... [checks notes] ... in 2010! Definitely ripe to be freshened up. If you've got something that is smaller, faster, maintained, and covers more formats than we currently support, that's about as good as things get. Definitely go for it. Looks like bcdec gives a choice of unlicense or MIT, and either is fine for inclusion in OIIO.

I don't have a strong opinion about embedding vs pulling from github. I suppose if we pull, like fmt, maybe it's a little easier to ensure we don't retain an old version just festering in our code base. For the approach we take with fmt, there's an explicit version number or commit in our build files, so it's really apparent that we should update it from time to time. Whereas fully embedding the file, it's easy to just forget about it or not quite know which version we have.

I'm comfortable with only having a reader for now. I'm definitely not averse to having a writer, but it's not something people have asked for; we've been read-only for this format for many years now without complaint. But I defer to your judgment -- if you are against read-only support and want to implement it, or simply want to leave the option open for future expansion to encoding without having to switch libraries again, and a different choice than bcdec is better in that case, that's fine too. Totally up to you.

lgritz pushed a commit that referenced this issue Jul 2, 2022
Implements support for BC4, BC5, BC6H (unsigned and signed) and BC7
GPU texture compressed formats in DDS reader (#2338).

- BC4: loaded into 1 channel uint8,
- BC5: loaded into 2 channel uint8,
- BC6H: loaded into 3 channel half,
- BC7: loaded into 4 channel uint8.

This is implemented by replacing whole of libsquish (~4700 lines of
code) with bcdec.h (https://github.com/iOrange/bcdec, ~1300 lines of
code). bcdec.h has an advantage of being faster, smaller and supports
all BCn formats for decoding.

bcdec.h license is MIT or Unlicense (aka public domain), updated all
the relevant third party / license files that I could find.
@aras-p
Copy link
Contributor

aras-p commented Jul 2, 2022

This could be resolved as "done" now, I think.

@lgritz
Copy link
Collaborator

lgritz commented Jul 2, 2022

agreed

@lgritz lgritz closed this as completed Jul 2, 2022
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

No branches or pull requests

4 participants