[Nouveau] Findings on pre-NV50 miptree layout

Luca Barbieri luca at luca-barbieri.com
Fri Jan 8 13:56:50 PST 2010


I wrote a tool for automatically finding out the texture layout for Gallium
drivers.
You can find it attached to
http://sourceforge.net/mailarchive/forum.php?thread_name=ff13bc9a1001081140y18450c3ejdfac25c9260fd367%40mail.gmail.com&forum_name=mesa3d-dev
.
Here are the findings from running it.

The result is that our miptree layout code is partially broken, and overly
complex.
In particular:
1. 3D textures are broken because they are not laid out like cube maps, but
first by level and then by face
2. Swizzled 3D texture are all 3 texture coordinates swizzled together
3. Cube maps have their faces 128 byte aligned, not only 64 like in my patch
or unaligned like without it (not applied IIRC).
4. Swizzled 2D/3D/cube textures don't have any gaps, except for cube map
face alignment. The current code contains a strange dimension check.

I'm in the process of rewriting the miptree layout code and all the 2D
engine code to account this (and to support all case, including unswizzling
and 3D-swizzling).

Here are the findings on NV40.

Not sure what happens with compressed textures (which may be currently
broken since Doom3 misrenders in non-Ultra quality).
I'll check that once the 2D code is otherwise finished and working

* Swizzled 1D/2D/3D textures
Mipmaps are laid sequentially with no gap in between.
Each mipmap is laid "swizzled".
To get the swizzled address of a texel, take an x bit, then an y bit, then a
z bit and so on.
If you exceed a dimension, skip taking their bits.
This means in particular that 3D textures are "3D swizzled": zyxzyxzyx...
The blob loads swizzled 3D textures with the CPU.
It seems that there is no GPU hardware that can write to swizzled 3D
textures (except of course for mapping it as something else and computing in
a fragment shader).

* Swizzled cube maps
Cube maps are sequences of 2D textures, each aligned to 128 bytes.
The hardware seems to have sampling support for non-square cube maps (not
supported by any API afaik) but lays them out as if their height were equal
to the width.

* Linear textures
In linear textures all images have the same pitch, which can apparently be
any value (even 4), aligned to bytes per pixel.
1D textures and 2D textures are laid out in the obvious way.
3D textures are laid with contiguous mipmaps, each containing a 2D texture
for each zslice.
Cube maps are laid with contiguous faces, each a 2D texture. No special face
alignment is used (they will still be aligned to the pitch of course).


# Alignment requirements
Render target pitch must be a multiple of 64 and greater than 0.
For swizzled targets, the blob sets a width * bpp pitch. However, the
hardware seems to ignore pitch for swizzled targets.
Furthermore, the hardware can actually render to any swizzled surface size!
The offset must however be a multiple of 64, even for swizzled surfaces.

# GdiSubRect does not seem to work with SWIZZLED_SURFACE set as surface

# SWIZZLED_SURFACE wants a 64-byte aligned destination
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.freedesktop.org/archives/nouveau/attachments/20100108/a13b4267/attachment.htm 


More information about the Nouveau mailing list