mesa/main: rewrite mipmap generation code

The old mipmap generation code has a few problems:

1. It open-codes the format conversion, which is error prone, and it's
   hard to know if we're missing some formats. Manual inspection shows
   that we're indeed missing some less commonly used formats.

2. When downsampling between two miplevels with the same width (e.g a
   width of one), the code would read from outside the image.

3. It averages sRGB textures in gamma space. Whilte that's legal in GL
   (the filtering algorithm is undefined), it doesn't produce very good
   results. And it's not the same thing as util_gen_mipmap() does.

4. Similarly, it uses a box-filter for the stencil values. And while
   that's actually what the spec recomments (regardless of format), it's
   absolutely *not* what most applications would want. Using nearest
   sampling would make more sense.

5. It has requirements about the type and format returned by
   _mesa_uncompressed_format_to_type_and_comps() which other call-sites
   in mesa doesn't have. This is the real reason I want to get rid of
   it, because it ends up complicating the GLES read formats / types.

So, let's rewrite all of this, fixing all of the above. The result is
quite a bit shorter, and if this ends up being less performant, it's
unlikely that this matters, because we almost always use the GPU
accelerated code-path provided by util_gen_mipmap() anyway.

The new code works by a few identities: It uses the pack / unpack
helpers to convert the texture to a few reasonable intermediate formats,
so we keep the amount of open-coded averaging to a minimum. To do this
without heap-allocations, we introduce a concept of a "span", which has
a max fixed size, that can trivially be allocated on the stack.

We also add some more requirements to keep things sane; the higher level
do_row functions only allow the dest image to be half of the source
width or one (whichever is larger). This matches the high-level needs of
mipmap generation. The lower level do_span() function is a bit more
flexible, because that turns out to be helpful when implementing
do_span_3D(), where we want to avoid collapsing the inner dimension
twice.

Tested-by: Eric R. Smith <eric.smith@collabora.com>
Reviewed-by: Marek Olšák <marek.olsak@amd.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/29380>
This commit is contained in:
Erik Faye-Lund
2024-05-23 20:33:31 +02:00
committed by Marge Bot
parent cd37384985
commit dd8fb7139d

File diff suppressed because it is too large Load Diff