介绍D3DPOOL和Lock

2023-11-17

分类: DirectX 2013-02-28 00:21  322人阅读  评论(0)  收藏  举报

  D3D RUTIME的内存类型,分为3种,VIDEO MEMORY(VM)、AGP MEMORY(AM)和SYSTEM MEMORY(SM),
所有D3D资源都创建在这3种内存之中,在创建资源时,我们可以指定如下存储标志,
D3DPOOL_DEFAULT、D3DPOOL_MANAGED、D3DPOOL_SYSTEMMEM和D3DPOOL_SCRATCH。
VM就是位于显卡上的显存,CPU只能通过AGP或PCI-E总线访问到,读写速度都是非常慢的,
CPU连续写VM稍微快于读,因为CPU写VM时会在CACHE中分配32或64个字节(取决于CACHE LINE长度)
的写缓冲,当缓冲满后会一次性写入VM;SM就是系统内存,CPU读写都非常快,
因为SM是被CACHE到2级缓冲的,但GPU却不能直接访问到系统缓冲,所以创建在SM中的资源,
GPU是不能直接使用的;AM是最麻烦的一个类型,AM实际也存在于系统内存中,
但这部分MEM不会被CPU CACHE,意味着CPU读写AM都会写来个CACHE MISSING然后才通过内存总线访问AM,
所以CPU读写AM相比SM会比较慢,但连续的写会稍微快于读,
原因就是CPU写AM使用了“write combining”,而且GPU可以直接通过AGP或PCI-E总线访问AM。

如果我们使用D3DPOOL_DEFAULT来创建资源,则表示让D3D RUNTIME根据我们指定的资源使用
方法来自动使用存储类型,一般是VM或AM,系统不会在其他地方进行额外备份,当设备丢失后,
这些资源内容也会被丢失掉。但系统并不会在创建的时候使用D3DPOOL_SYSTEMMEM或D3DPOOL_MANAGED
来替换它,注意他们是完全不同的POOL类型,创建到D3DPOOL_DEFAULT中的纹理是不能被CPU LOCK的,
除非是动态纹理。但创建在D3DPOOL_DEFAULT中的VB IB RENDERTARGET BACK BUFFERS可以被LOCK。
当你用D3DPOOL_DEFAULT创建资源时,如果显存已经使用完毕,则托管资源会被换出显存来释放足够的空间。 
D3DPOOL_SYSTEMMEM和D3DPOOL_SCRATCH都是位于SM中的,其差别是使用D3DPOOL_SYSTEMMEM时,
资源格式受限于Device性能,因为资源很可能会被更新到AM或VM中去供图形系统使用,
但SCRATCH只受RUNTIME限制,所以这种资源无法被图形系统使用。 
D3DRUNTIME会优化D3DUSAGE_DYNAMIC 资源,一般将其放置于AM中,但不敢完全保证。
另外为什么静态纹理不能被LOCK,动态纹理却可以,都关系到D3D RUNTIME的设计,
在后面D3DLOCK说明中会叙述。

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

 

二 lock

 

如果LOCK DEFAULT资源会发生什么情况呢?DEFAULT资源可能在VM或AM中,如果在VM中,
必须在系统内容中开辟一个临时缓冲返回给数据,当应用程序将数据填充到临时缓冲后,
UNLOCK的时候,RUNTIME会将临时缓冲的数据传回到VM中去,如果资源D3DUSAGE属性不是WRITEONLY的,
则系统还需要先从VM里拷贝一份原始数据到临时缓冲区,这就是为什么不指定WRITEONLY会降低
程序性能的原因。CPU写AM也有需要注意的地方,因为CPU写AM一般是WRITE COMBINING,
也就是说将写缓冲到一个CACHE LINE上,当CACHE LINE满了之后才FLUSH到AM中去,
第一个要注意的就是写数据必须是WEAK ORDER的(图形数据一般都满足这个要求),
据说D3DRUNTIME和NV DIRVER有点小BUG,就是在CPU没有FLUSH到AM时,GPU就开始绘制相关资源产生
的错误,这时请使用SFENCE等指令FLUSH CACHE LINE。第二请尽量一次写满一个CACHE LINE,
否则会有额外延迟,因为CPU每次必须FLUSH整个CACHE LINE到目标,但如果我们只写了LINE中部分字节,
CPU必须先从AM中读取整个LINE长数据COMBINE后重新FLUSH。第三尽可能顺序写,
随机写会让WRITE COMBINING反而变成累赘,如果是随机写资源,不要使用D3DUSAGE_DYNAMIC创建,
请使用D3DPOOL_MANAGED,这样写会完全在SM中完成。

普通纹理(D3DPOOL_DEFAULT)是不能被锁定的,因为其位于VM中,只能通过UPDATESURFACE和
UPDATETEXTURE来访问,为什么D3D不让我们锁定静态纹理,却让我们锁定静态VB IB呢?我猜测可能
有2个方面的原因,第一就是纹理矩阵一般十分庞大,且纹理在GPU内部已二维方式存储;
第二是纹理在GPU内部是以NATIVE FORMAT方式存储的,并不是明文enRGBA格式。动态纹理因为表明
这个纹理需要经常修改,所以D3D会特别存储对待,高频率修改的动态纹理不适合用动态属性创建,
在此分两种情况说明,一种是GPU写入的RENDERTARGET,一种是CPU写入的TEXTURE VIDEO,
我们知道动态资源一般是放置在AM中的,GPU访问AM需要经过AGP/PCI-E总线,速度较VM慢许多,
而CPU访问AM又较SM慢很多,如果资源为动态属性,意味着GPU和CPU访问资源会持续的延迟,
所以此类资源最好以D3DPOOL_DEFAULT和D3DPOOL_SYSTEMMEM各创建一份,自己手动进行双向更新更好。
千万别 RENDERTARGET以D3DPOOL_MANAGED 属性创建,这样效率极低,原因自己分析。
而对于改动不太频繁的资源则推荐使用DEFAULT创建,自己手动更新,因为一次更新的效率损
失远比GPU持续访问AM带来的损失要小。

不合理的LOCK会严重影响程序性能,因为一般LOCK需要等待COMMAND BUFFER前面的绘制指令全部
执行完毕才能返回,否则很可能修改正在使用的资源,从LOCK返回到修改完毕UNLOCK这段时间GPU
全部处于空闲状态,没有合理使用GPU和CPU的并行性,DX8.0引进了一个新的LOCK标志D3DLOCK_DISCARD,
表示不会读取资源,只会全写资源,这样驱动和RUNTIME配合来了个瞒天过海,立即返回给应用程序
另外块VM地址指针,而原指针在本次UNLOCK之后被丢弃不再使用,这样CPU LOCK无需等待GPU使用
资源完毕,能继续操作图形资源(顶点缓冲和索引缓冲),这技术叫VB IB换名(renaming)。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

介绍D3DPOOL和Lock 的相关文章

  • D3D中的三种Buffer

    在D3D中 针对视窗有三种Buffer 它们分别是 Color Buffer Depth Buffer和Stencil Buffer Color Buffer在D3D中又称为Render Target 意思是最后着色的目标Buffer 就是
  • D3D纹理

    纹理映射是一种将图形施加到表面的技术 以简单的一堵墙为例 这种技术可以只需要两个绘制有砖纹理的三角形即可 这样就可以为表面增加大量的细节 而不必使用大量的多边形 纹理映射使用了图像数据并将图像数据绘制 映射 到表面上 该表面看上去就像有一幅
  • Direct3D VertexBuffer Lock() and Unlock() function

    Stack Overflow is a question and answer site for professional and enthusiast programmers It s 100 free no registration r
  • d3d制作场景地形

    一般可以先用d3d做地形的mesh 比如做一个100 100的网格 然后用photoshop做高度图 然后再程序里读取高度图数据 让mesh的每个顶点对应一个高度 http download csdn net source 855296 这
  • 成功编译RenderingPluginExample53的cpp项目的步骤

    备忘 unity中调用d3d功能的示例项目 两个方面的配置 1 为了在项目中能够找到d3d12 h d3d11 h d3d9 h等 做如下操作 在项目属性中 VC 目录 包含目录 中添加 C Program Files x86 Window
  • 高级纹理映射技术(6)

    高级纹理映射技术 6 对一些特殊的应用需要对纹理坐标进行处理 主要包括纹理坐标自动生成和纹理坐标变换 下图显示了纹理坐标的来源 处理过程以及到达光栅处理器的过程 纹理坐标自动生成 在Direct3D程序中 不仅可以在模型载入阶段或渲染阶段指
  • orge工具

    tortoisehg 3 2 1 x64 msi mercurial 3 2 1 x64 msi
  • 手把手教你如何配置和编译ogre 1.7.0 + cegui 0.7.1

    oiramario 博客园 首页 新随笔 联系 订阅 管理 随笔 423 文章 1 评论 838 手把手教你如何配置和编译ogre 1 7 0 cegui 0 7 1 ogre 1 7 0的下载 配置和编译指南 1 ogre 1 7 0的下
  • win10 graphedit存储的路径

    如果安装郭windows SDK的话 可能的存储位置为C Program Files x86 Windows Kits 10 bin x86 C Program Files x86 Windows Kits 10 bin x64
  • GLFW初体验

    GLFW初体验 GLFW 很遗憾 没有找到FW的确切含义 Wiki上没有 GLFW主页也没有 猜测F表示for W表示Window GLFW是干啥用的 一个轻量级的 开源的 跨平台的library 支持OpenGL及OpenGL ES 用来
  • fvf采用另外一种方式渲染

    if FAILED hr getActiveD3D9Device gt SetVertexDeclaration d3ddecl gt getD3DVertexDeclaration getGlobalInstanceVertexBuffe
  • D3D9Texture::_loadNormTex

    D3D9Texture loadNormTex D3D9Texture loadImpl
  • 欧拉角与四元数

    以下文章摘自wiki百科 对于在三维空间里的一个参考系 任何坐标系的取向 都可以用三个欧拉角来表现 参考系又称为全局坐标系 是静止不动的 而局部坐标系则固定于刚体 随着刚体的旋转而旋转 参閲右图 设定 x y z轴为全局坐标系的参考轴 称
  • 关于visual studio中的$(ConfigurationName)疑问

    关于visual studio中的 ConfigurationName 疑问 2012 12 02 16 09 15 转载 标签 it 分类 程序员之路 关于vs中的各种路径的值de查看方法 来源 http social msdn micr
  • 垂直同步到底要不要开?老司机教你G-Sync显示器的正确打开姿势

    一直以来我们都认为PC的画面效果取决于显卡 认为游戏的FPS值越高代表游戏越流畅 但实际上 显示器也是决定游戏帧数的重要一环 显卡将画面渲染并输出到显示器中 显示器接收GPU的信号并输出 然而 因为显卡性能和运行程序的差异 显卡一般无法以恒
  • Texture::getSourceFileType()

    Texture getSourceFileType
  • cocos2d-x 卡牌翻牌效果的实现

    cocos2d x 卡牌翻牌效果的实现 2012年07月25日 综合 共 3085字 字号 小 中 大 评论关闭 猴子原创 欢迎转载 转载请注明 转载自Cocos2D开发网 Cocos2Dev com 谢谢 原文地址 http www co
  • 三维旋转:旋转矩阵,欧拉角,四元数

    在介绍下面的文章前 大家如果接触到欧拉角的话 就一定要关注一个词 要顺规 在欧拉角体系里面 有12种顺规 这一点是好多文章没有让读书意识到 导致后面学习图形学里面的 heading pitch bank 时对不上号 一般百度百科里面说到的
  • Ogre引擎源码——资源之Skeleton

    Ogre引擎源码 资源之Skeleton 分类 OGRE 游戏开发 引擎开发 图形引擎 游戏引擎 2012 09 21 06 17 1231人阅读 评论 0 收藏 举报 引擎 animation vector binding pointer
  • OpenGL图形管线和坐标变换

    1 OpenGL 渲染管线 OpenGL渲染管线分为两大部分 模型观测变换 ModelView Transformation 和投影变换 Projection Transformation 做个比喻 计算机图形开发就像我们照相一样 目的就是

随机推荐