翻译自:http://msdn.microsoft.com/zh-cn/library/windows/desktop/bb172584(v=vs.85).aspx
定义资源缓存的存储位置。
VIDEO MEMORY(VM):
显卡上的显存,CPU只能通过AGP或PCI-E总线访问,读写速度都是非常慢的,CPU连续写VM稍微快于读,因为CPU写VM时会在CACHE中分配32或64个字节(取决于CACHE LINE长度)的写缓冲,当缓冲满后会一次性写入VM。
SYSTEM MEMORY(SM):
就是系统内存,存放在System Memory上的Resource是不能直接被GPU访问的,对于GPU来说是不可见的,这种资源CPU读写都很快,但必须经过拷贝到VM或AM中才能在GPU中渲染。
AGP MEMORY(AM):
实际也存在于系统内存中,只是这部分内存已经被Mapping为显存的一部分,不但CPU可以访问这部分内存,而且GPU也可以通过PCI-E/AGP总线透明访问这部分内存,就像显存一样,但GPU访问速度比显存慢,毕竟经过映射,而且还要走PCI-E总线进行读写。
CPU连续的写会稍微快于读,原因就是CPU写AM使用了“writecombining”,GPU访问AM内存比较慢。
D3DUSAGE_DYNAMIC会将资源放置在AM中。
D3DPOOL_DEFAULT:
此类资源不由D3D管理,常驻在显存或者AGP内存中渲染效率高;丢失需要重新创建;锁定读比较麻烦,一般设置为D3DUSAGE_WRITEONLY。
资源放置在显存或者AGP内存中,D3DPOOL_DEFAULT和D3DPOOL_MANAGED、D3DPOOL_SYSTEMMEM是不能同时存在的。
当设备丢失了(可能发生在窗口和全屏模式切换,或者不切换但修改分辨率),被D3DPOOL_DEFAULT创建的资源,在IDirect3DDevice9::Reset调用之前,必须被用release释放掉。使用D3DPOOL_DEFAULT创建资源时,如果内存不够用,那么managedresource会释放一些内存空间来满足需要。
D3DPOOL_DEFAULT内存池中的纹理是不能锁定的,除非是D3DUSAGE_DYNAMIC使用方式的纹理或者是私有、FOURCC、
驱动格式的纹理。一些使用driver特有的像素格式创建的纹理,无法被Direct3D runtime识别,也是可以锁定的。
与texture不同的是,swapchain back buffers, render targets, vertex buffers和indexbuffers都是可以锁定的,
去访问没有成功锁定的纹理,你必须使用IDirect3DDevice9::UpdateSurface, IDirect3DDevice9::UpdateTexture,
IDirect3DDevice9::GetFrontBufferData,and IDirect3DDevice9::GetRenderTargetData.
D3DPOOL_MANAGED is probably a better choicethan D3DPOOL_DEFAULT for most applications.
适用情况:有时候我们希望将某些资源一直放在显存里,以提高访问速度。同时使用D3DUSAGE_WRITEONLY标记会提高效率。
例子:游戏中使用的光标贴图,在游戏运行过程中一直要使用,可以直接创建在显存中。
如果数据需要高频率更新(不断的Lock, Unlock),也需要使用D3DPOOL_DEFAULT,同时使用D3DUSAGE_DYNAMIC标记。这意味着此资源会被创建在AGP Memory中。
例子:使用CPU进行物理运算的粒子系统、使用CPU计算蒙皮的骨骼动画。
注意:
D3DPOOL_MANAGED 不一定会将贴图资源放到显卡里面,换句话说通常只有在贴图被使用的时候才会交换到显存中。
所以用D3DPOOL_MANAGED创建的时候数据大多数情况只是内存之间的传输(如果显卡总线忙也不影响继续加载),
而D3DPOOL_DEFAULT则在创建的时候就要不断的向显存中传输数据。如果你的资源是一起创建的,很容易造成了显卡
总线满载,后面的贴图要等待前面的贴图完全传送到显卡上了,才能开始传输。这种排队可能是造成你过慢的原因。
我原来也尝试过 用D3DPOOL_DEFAULT,总觉得丢失回复的速度太慢了。另外显存交换也非常麻烦,
综合起来还不如D3DPOOL_MANAGED,所以贴图资源不建议使用D3DPOOL_DEFAULT。
D3DPOOL_MANAGED:
交给D3D托管,渲染效率一般(系统RAM/AGP内存/显存中都有); 设备丢失会自动恢复; 锁定读写效率较高。
资源交给D3D自动管理,资源会在系统内存中备份一份,在资源需要渲染的时候,会自动拷贝一份到AGP内存、显存中进行渲染。
当设备丢失时,D3D会自动恢复显存中的数据。
D3DPOOL_MANAGED的资源可以自由的锁定。
但是只有系统内存中的副本资源数据可以直接的修改,当需要渲染的时候D3D会自动的拷贝到AGP内存和显存中。
适用情况:由于D3D自己的资源管理方案很高效、使用简单,游戏中大部分资源都可以使用此标识创建。
例子:游戏中使用的大部分纹理贴图,静态模型。
D3DPOOL_SYSTEMMEM:
直接放置在系统中,渲染效率较差需要用UpdateSurface或UpdateTexture拷贝到D3DPOOL_DEFAULT创建的资源,
设备丢失时候不需要重新创建资源,锁定很方便CPU处理较快。
资源放置在系统RAM,但是不会减少RAM的可访问页,不能够被Direct3D 设备直接访问。当设备丢失的时候,这些资源不需要
重新创建。这些资源可以被锁定(读写),可以通过IDirect3DDevice9::UpdateSurfaceor IDirect3DDevice9::
UpdateTexture函数,将该类型的资源数据,设置为用D3DPOOL_DEFAULT创建的资源的数据来源。
使用:
对于需要高频CPU读写处理的数据,推荐使用这种方式。
D3DPOOL_SCRATCH:
直接放置在系统中,不能直接的交给D3D渲染,设备丢失时候不需要创建资源,不被设备像素格式限制可以创建锁定拷贝。
这些资源放置在系统RAM中,当设备丢失时不需要重新创建数据。这些数据不被设备大小和像素格式的限制。正因为如此,
这些资源不能被Direct3D访问,不能够设置为纹理或者设置为渲染目标。然而,这些资源之间总是可以被创建,锁定和拷贝。
使用:
Directx 9引入这种内存池的原因是由于它从API中删除了CreateImageSurface()的函数。通常,D3DPOOL_SCRATCH是连同CreateOffscreenPlainSurface()一起使用的,后者将返回一个与之前通过CreateImageSurface()来创建的、具有相同特征的表面。因此,它主要用于创建图像表面。
D3DPOOL_FORCE_DWORD:
强制编译器将本参数类型编译为32bit,如果没有使用这个值,一些编译器将会把本参数编译为一个大于或小于32bit的值。
这个值现在是没有使用的。