When creating and manipulating resources Direct3D provides a number of flags that you can set to indicate how you intend to use the resource. By telling Direct3D this it can work with the video card driver and place resources in the best place for optimised rendering. There are three main sets of flags described on this page:
- Memory pool - which memory pool to place a resource in
- Usage - how you intend to use the resource
- Lock flags - how you intend to work with the data when you lock it
When creating vertex buffers, index buffers, textures etc. Direct3D requires you indicate a memory class into which to place the new resource. This is known as a pool and Direct3D defines the following:
Each of these is described below:
Places the resource in the best place for speed given the usage hints you provide at creation. Normally this will place the resource in video memory or the fast AGP memory. If the resource is a texture it cannot be locked unless it is marked as a dynamic texture. Other resources like back buffers, render targets, vertex buffers and index buffers can be locked but there will be a performance penalty. If the Direct3D device is lost (due to mode change etc.) then resources declared as default must be released (prior to a reset) and recreated when the device is gained again. Make sure you always indicate that this resource is write only as well (see write only usage).
Note: when a default resource is created managed resources may be removed from video card memory to allow room for the default resource. For this reason it is best to always allocated default resources before managed ones or call EvictManagedResources before allocating non managed resources. Try never to create any non managed resources after creating managed ones e.g. create them at game start or level load but not during game play. If you have to create them then call EvictManagedResources first but be prepared for a speed hit.
This is the preferred memory pool. Direct3D maintains a system copy of the resource (in system RAM) and makes a copy into video ram or AGP memory as needed. One advantage of this is that these resources do not need to be freed and recreated when the device is lost. Another advantage is that all resources created in managed memory can be locked. Direct 3D will lock the system memory copy and then update the one in device memory as required. Managed memory is the preferred method as Direct3D can work directly with the video card for optimum resource positioning. The advice is to use managed for everything and then later on, if you want, go back and make changes to tweak performance.
Normally places resources in system RAM or at least non device assessable RAM. This will be for resources that you do not directly wish to render. These resources can be locked and do not need recreating on a lost device. One use of this resource pool is as a source to copy into a D3DPOOL_DEFAULT allocated surface or texture using UpdateSurface or UpdateTexture
Places resources in system RAM. These resources can be locked and do not need recreating on a lost device. The great advantage of this resource type is that it is not restricted by the video card e.g. many video cards require texture dimensions to be power of 2 only so if you wish to load a non power of 2 texture this is the only pool into which you can load it. The disadvantage of course is that resources in this pool cannot be accessed by the device and so cannot be used during rendering. This pool is generally used for pre-processing of data e.g. you could load a large texture into a scratch memory surface and then slice it into smaller pieces and create normal device textures with it.
Use managed D3DPOOL_MANAGED most often, a copy will be placed in the optimal place by Direct3D in conjunction with the video card and they can be locked and manipulated and do not need recreating. If you need to use D3DPOOL_DEFAULT resources make sure you allocate them before any managed ones or use EvictManagedResources first. D3DPOOL_SYSTEMMEM resources are useful for data that will be used to update surfaces or textures. The D3DPOOL_SCRATCH pool is a place where you can manipulate date without any restrictions from the graphics device.
Resource Usage Hints
When creating resources Direct3D provides a flag where you can indicate how you will using the resource. Note that this is only a hint to Direct3D and there is no guarantee of what Direct3D will do however it is a very useful mechanism for getting optimal performance from your rendering. Direct3D provides the following usage flags:
Rather than go through these in order I will look first at the most commonly used ones:
Can be provided for any resource other than a surface. You use this flag to indicate that the resource is going to be manipulated regularly e.g. written over every frame. Direct3D will generally place this resource in AGP memory. If you do not use this flag Direct3D assumes a resource is static i.e. you are never going to manipulate it. Note that you cannot indicate dynamic usage for D3DPOOL_MANAGED created resources, instead you should use D3DPOOL_DEFAULT. Doing this means that Direct3D and the video card will decide which is the best place to put the resource. In general this will be AGP memory for vertex buffers and either AGP memory or video memory for index buffers. For best results combine with the D3DUSAGE_WRITEONLY flag if possible. The bottom line is that if you ever lock, say a vertex buffer, more than once you should indicate it is dynamic rather than static.
Can be specified only for vertex and index buffers. Indicates to Direct3D that you are only going to ever write to this resource and never read from it. If you are never going to read from the resource this flag can give great speed increases as the device can place the resource in the best place for rendering. If you use this flag and attempt to read from the resource it will fail. Resources created in the D3DPOOL_DEFAULT should always be marked as write only or you will lose a lot of performance.
Indicates that vertex processing should be done in software as opposed to hardware. Use when you create a device with software processing but avoid when using hardware processing.
Causes an automatic generation of mipmaps for texture resources. Note that this cannot be used with resources in system memory (D3DPOOL_SYSTEMMEM).
Indicated that this resource will be a depth stencil buffer. Can only be used with D3DPOOL_DEFAULT resources.
Indicates that this texture resource will be a displacement map.
Indicates that the vertex buffer will never require clipping. This is useful for buffers with already transformed vertices (D3DFVF_XYZRHW) as normally a vertex buffer will require extra data for clipping flags. Clipping flags are used when rendering outside or partially outside the viewing area so if you use this flag you must be sure you will never render off screen. Note that the D3DRS_CLIPPING render state must also be set to false.
Indicates that the vertex buffer will be used to draw N-patches.
Indicates that the vertex or index buffer will be used to draw point sprites. Note that if the device cannot handle hardware point sprites this will cause the resource to be loaded into system memory.
Indicates that the vertex buffer is used for drawing higher order primitives.
The resource will be a render target i.e. you are going to render a scene into it (useful for things like mirrors etc.). This can only be specified for textures and surfaces and can only be used for resources in the D3DPOOL_DEFAULT memory pool.
Locking and reading / writing flags
When locking resources and reading or writing them you can provide flags to Direct3D to help optimise performance. The flags are shown below:
Can be specified for texture, vertex and index buffers. Indicates that your application will overwrite every location in the locked resource with a write only operation. Should only be used with resources indicated as dynamic. Note that you must update the whole of the resource and not just a part of it. This flag can lead to big speed improvements. For vertex and index buffers Direct3D discards the previous contents and provide a new resource while still rendering from the old one - hence no stall occurs (the old one is thrown away once finished with). However be aware that if you do a lot of discards per frame the AGP memory usage will climb as you are always getting a new resource created.
By default when you lock a resource it is marked as 'dirty' which means it may need updating in card memory for example.
Note that this is only relevant for 16 bit Windows (95/98/ME). When a lock occurs normally a critical section is entered forcing no display mode changes to occur during the time of the lock. This can be time consuming but does give other processes time to run.
Indicates that your program will never write to the resource
Indicates that during this lock you will not overwrite any data in the index or vertex buffer. This allows the driver to keep rendering with the buffer, otherwise the driver would need to finish rendering before the lock process can be completed. You use this flag if you are going to lock a buffer several times a frame to append to it. This is often used for techniques like text rendering or sprites where you add to a buffer in a loop e.g. you maintain where you are in the buffer and append items until you reach the end. When the end is reached you then do a D3DLOCK_DISCARD and start again.