D3DPOOL详解

Posted xuhao_xuhao

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了D3DPOOL详解相关的知识,希望对你有一定的参考价值。



翻译自: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读写都很快,但必须经过拷贝到VMAM中才能在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的值。

这个值现在是没有使用的。

以上是关于D3DPOOL详解的主要内容,如果未能解决你的问题,请参考以下文章

初步了解3D纹理和材质

线路板的表面处理详解

关于Unity中蒙皮网格和布料的使用

火星时代系列所有视频教程集合

在网格加载和处理期间如何转换蒙皮网格?

SceneKit 错误加载蒙皮角色