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

Simplify solid-color BC7 transcoding #160

Closed
lexaknyazev opened this issue Jul 20, 2020 · 9 comments
Closed

Simplify solid-color BC7 transcoding #160

lexaknyazev opened this issue Jul 20, 2020 · 9 comments

Comments

@lexaknyazev
Copy link
Contributor

The spec and the source code suggest trying to use BC7 mode 6 first. However, the g_bc7_mode_5_optimal_endpoints array has zero errors for all 256 values, thus always providing lossless results.

@richgel999 could you please verify?

@richgel999
Copy link
Contributor

richgel999 commented Jul 20, 2020

One thing the spec doesn't mention is the output data entropy of the output BC7 data, which all other things being equal we want to reduce. This is why I originally preferred mode 6.

Using BC7 mode 6 first (over mode 5) is preferred because it's more commonly used across a wide range of textures. An LZ codec would be able to squeeze more bits from the solid color blocks if they used mode 6 vs. 5.

Does this make sense? But yea, otherwise it looks like a UASTC transcoder could always use BC7 mode 5.

image

@lexaknyazev
Copy link
Contributor Author

Sorry, I'm not following. The transcoder's output is supposed to be uploaded to the GPU. How is LZ relevant there?

@richgel999
Copy link
Contributor

richgel999 commented Jul 20, 2020

Because one additional use case of Basis Universal UASTC (that we definitely want to preserve, although this is likely not useful or interesting for KTX2 purposes) is to encode to RDO UASTC, then immediately transcode that to plain ASTC or BC7 and ship that data (which gets compressed with LZ). The more mode 6 gets used, the better for this use case.

A transcoder that is only intended for the common use case (upload to GPU) can do whatever it wants on solid color blocks, as long as the errors are the same. I'll update the spec.

@richgel999
Copy link
Contributor

I've updated the spec with a note about this. I'll spend more time on this later today or tomorrow. Thanks for pointing it out.

@lexaknyazev
Copy link
Contributor Author

The more mode 6 gets used, the better for this use case.

Thanks for the clarification. I wasn't aware of such use case.

A transcoder that is only intended for the common use case (upload to GPU) can do whatever it wants on solid color blocks, as long as the errors are the same.

Looking again at the source code, it seems that the final error is always 0. The only difference is that mode 5 is used only when the error is non-zero with mode 6. So we could always require lossless transcoding of solid blocks.

@richgel999
Copy link
Contributor

So we could always require lossless transcoding of solid blocks.

Yes, exactly. I'll update the spec.

@richgel999
Copy link
Contributor

I've updated the spec to clarify that you can always use mode 5. Thanks a lot!

@lexaknyazev
Copy link
Contributor Author

It turns out that BC7 mode 5 endpoints could be computed like this, without any loops:

e_lo = color >> 1;
e_hi = (color >> 1) + (color & 1) - (color >> 7);

@richgel999
Copy link
Contributor

Nice - thanks for this! When I do another pass on the transcoder, I'll integrate this.

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

2 participants