天天看点

D3DPOOL 用法分析

所有D3D资源都创建在以下这3种内存之中。

VIDEO MEMORY(VM)、AGP MEMORY(AM)和SYSTEM MEMORY(SM)

VM,显卡上的显存,CPU只能通过AGP或PCI-E总线访问,读写速度都是非常慢的,CPU连续写VM稍微快于读,因为CPU写VM时会在CACHE中分配32或64个字节(取决于CACHE LINE长度)的写缓冲,当缓冲满后会一次性写入VM。

SM,就是系统内存,存放在System Memory上的Resource是不能直接被GPU访问的,对于GPU来说是不可见的,这种资源必须经过拷贝才能运用到GPU的渲染中。

AM,实际也存在于系统内存中,只是这部分内存已经被Mapping为显存的一部分,不但CPU可以访问这部分内存,而且GPU也可以通过PCI-E/AGP总线透明访问这部分内存,就像显存一样,但GPU访问速度比显存慢,毕竟经过映射,而且还要走PCI-E总线进行读写。

创建资源时的D3DPOOL标志有:D3DPOOL_DEFAULT、D3DPOOL_MANAGED、D3DPOOL_SYSTEMMEM和D3DPOOL_SCRATCH。

D3DPOOL_DEFAULT,则表示让D3D RUNTIME根据我们指定的资源使用方法来,存储在最适合给定资源访问的内存中,只会是VM或AM。系统不会在其他地方进行额外备份,因此当设备丢失后,这些资源内容也会被丢失掉。当你用D3DPOOL_DEFAULT创建资源时,如果显存已经使用完毕,则托管资源(D3DPOOL_MANAGED标识创建)会被换出显存来释放足够的空间。这里需要注意的是:虽然D3DPOOL_DEFAULT标识创建的VB IB 可以被LOCK,但D3DPOOL_DEFAULT的纹理是不能被LOCK的,除非是动态纹理。

D3DPOOL_SYSTEMMEM,资源存储在SM中,优势在于:设备丢失后,资源不需要重新创建。另外,可以在池中锁定和更新资源。对于需要通过软件来处理的数据,推荐使用这种方式。

D3DPOOL_SCRATCH,临时池,资源存储在SM中,并且当设备丢失时,将无法重新创建它。这种设备丢失情况可能会发生在窗口模式和全屏模式之间切换时,或在这两种模式中改变分辨率时。Direct3D设备无法访问这些资源,他们也不能被设置为纹理或渲染目标,然而,他们总是可以被成功创建出来、被锁定或被复制。Directx 9引入这种

内存池的原因是由于它从API中删除了CreateImageSurface()的函数。通常,D3DPOOL_SCRATCH是连同CreateOffscreenPlainSurface()一起使用的,后者将返回一个与之前通过CreateImageSurface()来创建的、具有相同特征的表面。因此,它主要用于创建图像表面。

D3DPOOL_MANAGED,表示让D3D RUNTIME来管理资源,被创建的资源会有2份拷贝,一份在SM中,一份在VM中。创建的时候放置在SM中,在GPU需要使用资源时D3D RUNTIME自动将数据拷贝到VM中去,当资源被GPU修改后,RUNTIME在必要时自动将其更新到SM中来,而在SM中修改后也会被UPDATE到VM去中。所以被CPU或者GPU频发修改的数据,尽量不要使用托管类型,这样会产生非常昂贵的同步负担。其优势在于:LOST DEVICE发生后,RESET时RUNTIME会自动利用SM中的COPY来恢复VM中的数据。 

技巧:最好在D3DPOOL_MANAGED资源分配之前,分配基于D3DPOOL_DEFAULT的资源,这样就能确保必须使用VM的资源能够率先得到足够的空间,而不至于VRAM先被D3DPOOL_MANAGED的资源填满。因为D3DPOOL_MANAGED在VM不够用的情况下进行的分配操作不会失败(在正式使用之前它们可以呆在SM/AM里),但D3DPOOL_DEFAULT却不然。

继续阅读