Mipmap creation - done in hardwhere, when?

Started by
9 comments, last by Krohm 17 years, 8 months ago
Hey all. My goal is to find the fastest way to load a texture. I currently store them as .DDS files, and I use D3DXCreateTextureFromFile(). This automatically creates the mipmap chain for me. I know that I can create and store the mipmap chain in a .DDS ahead of time, but that is not an option at the moment, as I am also trying to save space. My question is: Is there a certain format (bmp, dds, etc) that most hardware likes to have, in order for mipmap generation to be done in hardware right away? That is, if I chose some format that D3DX supported, but the downsampling wasn't supported in hardware for that format, the card would have to convert to, say, a BMP, and then downsample, which would be slower. So I'm wondering which supported DX9 texture formats (if not all) can be downsampled immediately without any expensive software D3DX behind-the-scenes conversion. If no one knows, I'll just be going on profiling results, which I may likely do anyhow. From the SDK: "Consider using DirectDraw surface (DDS) files. Because DDS files can be used to represent any Direct3D 9 texture format, they are very easy for D3DX to read. Also, they can store mipmaps, so any mipmap-generation algorithms can be used to author the images." The italicized portion doesn't apply to me, as I said earlier. But since DDS can represent any format, I guess my question is: which is fastest to load?
--== discman1028 ==--
Advertisement
The hardware will only created mipmaps for render target textures that are created with the right usage Flag. For ”normal” textures it’s always the CPU. The GPU doesn’t know anything about different image formats. It’s always the D3DX library the reads the format and convert it the raw format. The difference between a bmp and an DDS file is that a BMP will only contain one image and the mipmaps are generate on the fly during loading. But a DDS file can contain pre-calculated mipmaps. In the end the loading time depends how fast your hard disk and your CPU are. If the CPU can calculate the mipmaps faster than you can load them this way will be faster. But the other case is possible to.
A bit of clarification needed :)

(edit again):
Quote:Original post by Demirug
The hardware will only created mipmaps for render target textures that are created with the right usage Flag.


- So normal textures can't have their mipmap chain calculated via the GPU? Why not? (Is it slower to do on the GPU?)

- So you're saying that the GPU will create the chain only from raw data (which D3DX feeds it)?

- And the GPU will only do this depending on the usage flag (otherwise, the CPU creates the chain)?


( Thanks Demirug - always a help. )
--== discman1028 ==--
Theoretical a GPU can create mipmap chains for every kind of texture but as such an operation is not done all the time it’s not optimized. The additional problem is that in the case of managed textures the System has to store a copy of each texture in the system ram to swap them around. If you let the GPU create the chains this need to be done every time a texture is swaped in the VRAM. This will make low memory situations even more slower.

Textures are always created as raw data memory block.

Yes, the mipmap generation is based on this usage flag. But it should only be used for render to texture effects were you need mipmaps to improve the quality.
I would be suprised if whether or not you had a mip-chain pregenerated in a .dds file significantly affected your loading times, unless you've got some huuuuge textures.

Have you actually measured any of this? Even on CD or DVD media, your seek times are way more important than your data transfer times. On HD, it's not going to matter unless the drive is seriously fragmented.

Also, you may also want to consider a few reasons for not having the hardware generate the mip-maps for you.

1) The way that most textures are handled, the filtering doesn't happen in linear color space.
2) The filter used is bilinear.
3) You lose the ability to control the mip contents.

1&2 were addressed in a Game Developer magazine article awhile back, and some code was provided to use better filtering, in linear color space, for better mips.

3 has a bunch of uses. One of the more common ones is to sort of use mipping like a control over detail mapping. For example, a lot of normal maps used for specularity look pretty shimmery/sparkly/bad when not very close to the camera. So, you could have the lower-level mips tend towards all upwards-facing (assuming tangent space normals), so as an object moves away, it would lose detail gracefully, in a way that you wouldn't get with auto-generated mip-maps.
Quote:Original post by JasonBlochowiak
I would be suprised if whether or not you had a mip-chain pregenerated in a .dds file significantly affected your loading times, unless you've got some huuuuge textures.

We knocked about 20 seconds off our load time by using pre-generated mips in a DDS. The problem is when a file is DXT compressed, D3DX uncompresses it, creates mips, and compresses each mip level, all in software.
Quote:Original post by JasonBlochowiak
1&2 were addressed in a Game Developer magazine article awhile back, and some code was provided to use better filtering, in linear color space, for better mips.

I always found HW mipmaps to be good enough... could you please point out the article? I also have GDM subscription but I don't remember about this.

Previously "Krohm"

Quote:Original post by discman1028
Hey all. My goal is to find the fastest way to load a texture. I currently store them as .DDS files, and I use D3DXCreateTextureFromFile(). This automatically creates the mipmap chain for me.

I know that I can create and store the mipmap chain in a .DDS ahead of time, but that is not an option at the moment, as I am also trying to save space.

If you want to save space and have fast loading you should look at storing your textures in a compressed format with pre-generated mipmaps. PNG is not a bad choice for a storage format as it's losslessly compressed and has fairly wide support. With PNG you'd need to have a separate file for each mip level though. An alternative is to store a DDS with a mip chain and then zip the DDS to save space. This is a better choice if you're using DXT compressed textures as DXT compression is quite expensive. With a reasonably fast compression / decompression method like zip it can actually be faster to load than loading uncompressed data because CPU's and memory are so much faster than hard disks that it's quicker to load less data and spend more time on the CPU processing it.

Generating mipmaps on the fly at load is slow (generating a mipmap for a large texture is quite expensive) and as mentioned by others is not going to give you the highest mipmap quality since runtime mipmap generation is usually optimized for speed rather than image quality.

Game Programming Blog: www.mattnewport.com/blog

Quote:Original post by Namethatnobodyelsetook
Quote:Original post by JasonBlochowiak
I would be suprised if whether or not you had a mip-chain pregenerated in a .dds file significantly affected your loading times, unless you've got some huuuuge textures.

We knocked about 20 seconds off our load time by using pre-generated mips in a DDS. The problem is when a file is DXT compressed, D3DX uncompresses it, creates mips, and compresses each mip level, all in software.


Yeah, that would be slow. I wouldn't expect to see any D3DX calls in production code, though.

Anyways, I should have been clearer: Data read and transfer times are unlikely to be a bottleneck for textures unless they're very large. Things like whether or not each texture is stored as an individual file, or as part of a packed file, are much more likely to have a significant impact on level startup times than whether or not the mip data is stored on disk. I would expect this to be true, even on slow media like CD or DVD.
Quote:Original post by Krohm
Quote:Original post by JasonBlochowiak
1&2 were addressed in a Game Developer magazine article awhile back, and some code was provided to use better filtering, in linear color space, for better mips.

I always found HW mipmaps to be good enough... could you please point out the article? I also have GDM subscription but I don't remember about this.


This was back in December 2001 and January 2002. I believe all the source you need is here, plus it looks like there's a pre-built executeable in there so you can take a look at the comparisons.

Hardware mipmaps are gamma-space bilinear filtered integer images. They're just not going to compare well with linear space floating point filters with a ton of taps.

This topic is closed to new replies.

Advertisement