I wrote a tool for automatically finding out the texture layout for Gallium drivers.<br>You can find it attached to <a href="http://sourceforge.net/mailarchive/forum.php?thread_name=ff13bc9a1001081140y18450c3ejdfac25c9260fd367%40mail.gmail.com&forum_name=mesa3d-dev">http://sourceforge.net/mailarchive/forum.php?thread_name=ff13bc9a1001081140y18450c3ejdfac25c9260fd367%40mail.gmail.com&forum_name=mesa3d-dev</a>.<br>
Here are the findings from running it.<br><br>The result is that our miptree layout code is partially broken, and overly complex.<br>In particular:<br>1. 3D textures are broken because they are not laid out like cube maps, but first by level and then by face<br>
2. Swizzled 3D texture are all 3 texture coordinates swizzled together<br>3. Cube maps have their faces 128 byte aligned, not only 64 like in my patch or unaligned like without it (not applied IIRC).<br>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.<br>
<br>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).<br><br>Here are the findings on NV40.<br><br>Not sure what happens with compressed textures (which may be currently broken since Doom3 misrenders in non-Ultra quality).<br>
I'll check that once the 2D code is otherwise finished and working<br><br>* Swizzled 1D/2D/3D textures<br>Mipmaps are laid sequentially with no gap in between.<br>Each mipmap is laid "swizzled".<br>To get the swizzled address of a texel, take an x bit, then an y bit, then a z bit and so on.<br>
If you exceed a dimension, skip taking their bits.<br>This means in particular that 3D textures are "3D swizzled": zyxzyxzyx...<br>The blob loads swizzled 3D textures with the CPU.<br>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).<br>
<br>* Swizzled cube maps<br>Cube maps are sequences of 2D textures, each aligned to 128 bytes.<br>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. <br>
<br>* Linear textures<br>In linear textures all images have the same pitch, which can apparently be any value (even 4), aligned to bytes per pixel.<br>1D textures and 2D textures are laid out in the obvious way.<br>3D textures are laid with contiguous mipmaps, each containing a 2D texture for each zslice.<br>
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).<br><br><br># Alignment requirements<br>Render target pitch must be a multiple of 64 and greater than 0.<br>
For swizzled targets, the blob sets a width * bpp pitch. However, the hardware seems to ignore pitch for swizzled targets.<br>Furthermore, the hardware can actually render to any swizzled surface size!<br>The offset must however be a multiple of 64, even for swizzled surfaces.<br>
<br># GdiSubRect does not seem to work with SWIZZLED_SURFACE set as surface<br><br># SWIZZLED_SURFACE wants a 64-byte aligned destination<br><br>