Also congrats to Simon and Eyal on getting back in - not sure if there are any new DX MVP's, but it looks like no ones been kicked out, which is great!
So yeah, they let me back in... I hope they realise what they've let themselves in for [evil]. Work permitting I should get another chance to go visit them over in Seattle next March (ISTR Bill Gates is doing the keynote speech).
Just out of curiosity I added up my various DirectX specific forum contributions for the last year... a little over 2500 forum posts in 365 days. If ever there was proof I needed to get out more then that's it.
I've spent today working on the forum FAQ - still a little way to go, but the end is in sight. Got 5 more Direct3D entries and another 3-4 other entries to write up. If you have any thoughts on the 'getting started' entry, check this thread out.
In light of the chaos I caused last time, I think I'll see about writing up a summary of "what I like about C#" later this week. Seems I might've come across a bit more anti-C# than I intended [lol]
Anyway, in closing - another FAQ entry for your perusal...
D3D #13: Resource allocation best practices.
Direct3D applications tend to use a large number of resources of varying formats such that it becomes important to manage them effectively given the relatively limited amount of storage space available. Texture resources in particular can easily consume vast amounts of memory.
As with the majority of software, allocating and de-allocating resources is a relatively expensive operation. Where real-time performance is important it makes sense NOT to do any resource manipulation inside the core render-loop. Ideally all resources should be created at the start of the application, used in the core rendering loop and then released as the application is terminated. This cycle can be extended to include creation/release of resources at defined points in time - e.g. the loading screen(s) for a game.
Unless resources are limited it can be better to create a pool of resources that get created at the start of the application and then (re-)used as-and-when is necessary. This avoids the need to create/release resources at the point of use.
Micro-managing resources can be difficult; IDirect3DDevice9::GetAvailableTextureMem() will return the number of megabytes (expressed as bytes!) available for resources, but this rarely corresponds directly to the VRAM size printed on your graphic's card box (128, 256 or 512mb for example). Use this value for guidance only!
If your texture resources are stored with full mip-chains you may wish to consider using the D3DX_SKIP_DDS_MIP_LEVELS() macro - several of the D3DX creation functions (e.g. D3DXCreateTextureFromFileEx()) can use this to avoid loading high-detail levels. A simple use of this might be to link this with a level of detail setting - e.g. "high detail" skips no levels, "medium detail" skips two levels and "low detail" skips four levels.
Direct3D resources are assigned to one of four pools defined by the D3DPOOL enumeration although in practice it will be D3DPOOL_MANAGED and D3DPOOL_DEFAULT that are most heavily used. As a general rule of thumb, create all resources in D3DPOOL_MANAGED unless they specifically need to be located in D3DPOOL_DEFAULT (render-targets have this requirement); resources placed in the managed pool will be scheduled by the Direct3D runtime - swapped in (or out) of VRAM as appropriate. The runtime's scheduler rarely proves to be a performance problem, but if profiling does show it is then you can look at pushing key resources into D3DPOOL_DEFAULT (which stay resident in VRAM).
A useful trick is to make use of the D3DQUERYTYPE_RESOURCEMANAGER query (see Queries in the SDK documentation). This query is only available with the debug runtimes thus has limited use when doing real-world testing but can provide valuable guidance/insight during development. The query can give you general information (see D3DRESOURCESTATS) about what data the scheduler is moving around on a frame-to-frame basis. This combined with other profiling information can help to determine if resource usage/allocation is the cause of any performance problems.
Use of IDirect3DBaseTexture9::SetLOD() is rarely required, but can allow your application to influence the way the managed-pool resources are scheduled. You can use this method to give importance to textures most important to the game (e.g. signs, maps and other high-detail resources) and scale back importance of "background" textures. Whilst the runtime's scheduler is sophisticated it lacks the context that you as the application developer has available.
Another advantage received by using managed resources is that they will survive the device-lost scenario. Not only does it make application code simpler (less chance of memory leaks, less calls to recreate resources) it is often faster (re-loading all resources for disk is generally a slow process).
When creating resources it is best to create all D3DPOOL_DEFAULT resources before creating any D3DPOOL_MANAGED ones; this makes sure that those requiring VRAM residency are allocated space before those that don't. If VRAM is full then managed resources won't fail to be created (they just remain in system/AGP RAM until needed) but default pool resources will.