D3D资源管理

2023-10-30


摘要

受管贴图(Managed textures,也就是我们通常所谓的“自动管理贴图”),在DX6中首次被引入,经过一系列的改进和增强,在DX9中自动管理的资源类型增加到贴图,顶点缓冲,顶点索引缓冲,所有这些资源使用统一的公共接口。通过使用D3D资源管理器,应用程序可以轻松的处理设备丢失、处理稍微过量的显存使用。

有时开发者在使用受管资源会遇到一些困难,这部分归咎与系统的抽象特性。在大多数情况下使用受管对象是不错的选择,但有时出于性能考虑也会使用非托管资源。这篇文章将讨论一般情况下如何处理资源,受管与非受管资源的行为差别。

 

内容

l         显示内存

l         受管资源

l         驱动管制资源

l         默认资源

l         系统内存资源

l         一般性的建议

 

显示内存

为了使得资源可以利用显存,GPU需要通过内存访问定位他。GPU访问(Local video memory)显存是非常高效的,并且某些资源(例如RenderTarget,深度、模板缓冲)必须在本地显存(Local video memory)定位。由于AGP的出现,GPU可以直接访问部分系统内存,而这部分系统内存区域就是所谓的非本地显存(non-local video memory),当然这部分内存(显存)也是不能挪做它用的。非本地显存仅能被GPU访问,与访问本地显存相比,其效率低一些。需要明确的是,所有AGP内存在设备丢失时都会失效,都需要在恢复他们。


一些集成显卡使用统一内存结构(Unified Memory Architecture),这样主内存可以被系统任何一个设备寻址。D3D支持UMA而不需要修改任何代码,这样我们把系统内存配置为本地显存,硬件确保资源的定位就像传统的结构一样进行工作。


受管资源

大部分资源应该使用POOL_MANAGED方式创建,即受管资源。所有受管资源将被创建在系统内存,在需要的时候复制到显存。当发生设备丢失时会自动copy系统内存到显存。既然不是所有受管资源都需要一次送入显存,这样你可以提交超过渲染每帧所必须使用的最小内存容量,但是这样会使得大量显存内容因为分页操作而写到磁盘上,这是非常耗时的。这也是为什么恢复设备如此耗时,因为需要将大量磁盘数据复制到显存。

DX会为每份资源在最后一次使用时加上时间戳,这样当显存分配失败时,它会释放那些最近最少使用的资源(LRU算法)。使用SetPriority函数可以标记资源的重要程度,重要的资源优于时间戳的判断,所以那些比较常用的资源应该设置高优先级,而不用担心因为时间戳过期而导致资源被释放。在DX9中,驱动程序提供的显存管理信息是非常有限的,运行时可能不得不清除大量资源用于分配足够的内存。设置适合的优先级是非常有用的,这样D3D不会清除那些马上又需要使用的资源。应用程序可以强制调用EvictManagedResources清除所有受管资源,但是如果下一帧又需要重新加载这些资源,这将是非常耗时的,不过这个函数在那些场景明显需要改变(比如进入下一个关卡)的情况下,还是非常有用的。

如果“当前帧”内需要非常多资源用于渲染,这将是件麻烦的事情,用前面的LRU方式调度资源效率就不太理想了,这个时候使用MRU资源调度方式取代,即优先清理那些比较活跃的资源。注意,这里“当前帧”的概念是指BeginScene和EndScene之间的需要渲染的帧。

开发人员如果想得到关于受管资源的更多信息,可以通过IDirect3DQuery9接口查询,但是这个接口仅能用于调试模式(debug runtimes),在发布版本中,应用程序不能依靠改接口的信息做任何假定。

了解资源管理如何工作可以帮助我们调试、调整程序,重要的是应用程序不要太过依赖当前的运行库(或者驱动程序)的资源管理方式,驱动更新有可能导致其行为发生变化,将来的D3D将会有套久经考验的资源管理方式。

驱动程序管理的资源

D3D驱动可以自由的实现“由驱动管理贴图”的特性,通过D3DCAPS2_CANMANAGERESOURCE段可以查询硬件驱动是否支持这个特性,这样驱动将代替D3D运行库管理资源。对于级少数的硬件是支持这个特性的,对于大多数硬件则不尽相同,你可以咨询你的产品提供商获得这方面信息。一般情况下,你可是使用D3DCREATE_DISABLE_DRIVER_MANAGEMENT方式创建设备,这样将由D3D运行库来管理资源。

缺省资源管理(非受管资源)

虽然受管资源非常简单,容易使用,高效,但是有时我们希望直接往显存里写东西,这种情况下我们需要使用POOL_DEFAULT方式创建资源。使用这种方式会增加程序的复杂性,代码需要应付所有设备丢失的情况,并需要谨慎考虑何时复制数据到显存。错误的指定USAGE_WRITEONLY标记或者锁定渲染目标(Render Target)将严重影响性能。

锁定POOL_DEFAULT类型的资源很可能导致GPU停止运转,这与POOL_MANAGED类型的资源是不同的,除非使用一些特性的指示标记。根据资源当前的位置不同,锁定后得到的指针也不相同,可能是一块临时的系统内存,也可能直接指向AGP内存。如果是临时的系统内存,Unlock后将把这段数据送入显存,这是因为如果显卡资源不是只写的(write-only),Lock的时候数据将不得不被送入一段临时的内存;如果指向的AGP内存区域,临时的拷贝是可以避免的,但是cache的行为将会降低性能。

为了避免在写入一整行数据(a full cache line of data)进入AGP内存区导致write-combing性能下降(一般是由于发生了一次读写周期),顺序的访问AGP内存是推荐的做法,如果你的程序需要随机的访问AGP内存,而你又不希望使用受管资源,那么你可以使用系统内存作为替代方案,这样当你生成了数据之后,可以lock后拷贝,这样不会带来太大的性能损失,这里的性能损失一般是由缓冲的“写搜索”操作引起。(注,这里关于词汇cache write-combing译者也不知道对应的中文含义,只能按照字面意思翻译,见谅)

对于某些类型的资源,使用LOCK_NOOVERWRITE标记会使添加数据比较有效率,但是多次的Lock,Unlock同一资源还是需要尽量避免的,适当的利用多种不同的锁定标记对于效率优化使非常重要的,就像填充锁定内存区域最好使用cache友好的(cache-friendly)数据访问方式一样。

受管资源和缺省资源混合使用

受管资源与非受管资源的混合分配使用可能导致显存碎块,并且扰乱受管资源使用的内存区域。最好在使用受管资源前使用非受管资源,或者使用受管资源后使用EvictManagedResources函数清除那些受管资源再使用非受管资源。记住,所有非受管资源都会常驻显存,这样其他内存需求就不能使用了。

注意,与以往的DX版本不同,在显存缺乏时,如果分配非受管资源失败,DX9会自动清除受管资源,这有可能导致潜在的显存碎块,甚至把资源放入不适当的地方(比如非本地内存的静态贴图区)。所以,最好在使用受管资源之前分配全部的非受管资源。

动态缺省资源

如果数据需要很高频率更新,那最好使用非受管资源,并使用USAGE_DYNAMIC标记,这样驱动会决定最适合的地方放置这些需要经常更新的数据。这通常意味着放置在非本地显存中,这样对于GPU来说,访问速度可能相对要慢一些。而对于UMA架构,驱动将会选择CPU访问效率较高的特殊地方放置这些数据。

这种用法(动态缺省资源类型)一般用于软蒙皮和基于CPU计算的粒子系统的顶点/顶点索引的Buffer填充,LOCK_DISCARD标记可以保证资源仍被使用的时候,锁定操作不会导致系统停止暂停工作。在这种情况下,使用受管资源会更新系统内存,然后拷贝到显存。对于系统的非本地内存,多余拷贝是不需要的。

标准的贴图是不允许锁定的,仅仅可以通过UpdateSurface和UpdateTexture函数更新。一些系统支持动态贴图,它可以通过配合使用LOCK_DISCARD标记进行锁定,但这需要检查D3DCAPS2_DYNAMICTEXTURES硬件能力。对于高动态贴图(如视频、程序生成贴图),最好使用非受管资源和系统内存资源,并且通过UpdateTexture函数更新贴图。对于高频度的粒子更新,UpdateTexture函数可能是最好的选择。

在有限的总线-内存带宽下,静态贴图资源应该使用POOL_MANAGED方式,这样可以确保它最好的利用本地显存,并有较好的效率。对于“半静态”资源,使用动态类型资源有时会获得更好的效率。

系统内存资源

资源可以使用POOL_SYSTEMMEM方式创建。但他们不能用于图形管线,他们仅能做为源数据用于更新POOL_DEFAULT类型的资源,这是通过UpdateSurface和UpdateTexture函数完成的。他们的锁定操作也非常简单,尽管他们同样可能因为前面提到的原因导致系统停止运转。

虽然是在系统内存中创建资源,但POOL_SYSTEMMEM所支持的资源格式和能力(比如最大尺寸)是受硬件、驱动限制的。同样是在系统内存中创建资源的POOL_SCRATCH则没有这方面限制,它支持所有格式和能力,但设备却不能直接访问它。SCRATCH类型资源一般用于内容创建工具。


一般性的建议

了解资源管理的技术实现细节对达成你的程序的性能目标是有非常大的帮助的,规划你的资源如何交给D3D并设计好的结构以便能及时加载必要的数据是一件非常复杂的工作,为此我们给出一些好的实践经验做为一般性的原则:

l         预处理你的资源。不要将耗时的加载资源、资源转换、资源优化丢给用户去做,虽然这样便于开发,但确让用户无法忍受。预处理这些资源可以加快加载,更快使用,你的用户也会发现你的程序跑的更快了。

l         避免在每帧创建过多的资源。对于过多的资源加载,可以把他们分到多帧里完成或者不要急于释放那些暂时不用的资源。

l         确保在一帧结束时已经断开了所有资源通道。(比如,顶点流,texture stages,顶点索引)。

l         对于贴图,建议使用压缩贴图(DXTn)格式,建议使用mip-map或者将小贴图拼接为大贴图使用。

l         建议使用顶点索引,这将减少数据传输量。

l         对于过渡的优化资源管理是需要谨慎的。如果你的程序过分依赖驱动、硬件和操作系统的某些特征,那么这些程序、硬件的修改将会导致潜在的性能问题。

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

D3D资源管理 的相关文章

  • LibGDX纹理混合与OpenGL混合功能

    在 libGdx 中 我试图创建一个成形纹理 采用完全可见的矩形纹理并将其遮罩以获得成形纹理 如下所示 在这里我在矩形上测试它 但我想在任何形状上使用它 我调查过本教程 http www learnopengles com tag addi
  • iPhone 上的全屏视频播放器是否有“onClose”事件?

    我在网站上使用 html5 视频播放器 当用户开始播放时 播放器进入全屏模式并播放视频 视频结束后 我看到ended事件并通过关闭视频播放器myvideo webkitExitFullScreen 现在 当玩家实际获得时我需要另一个事件cl
  • 将rtsp视频流转换为http流

    我有一个实时视频流的 rtsp URL 我想将其作为 HTTP 流进行访问 有人可以告诉我是否有任何组件可以放在我的服务器上来执行此操作 我不知道如何实现这一点 请注意 Thanks 我想说你最好的选择是使用 FFmpeg 或 VLC 两者
  • 在一个屏幕上合并 2 个图像输出(HDMI、DVI、VGA 或其他)

    我正在寻找一些不常见的东西 一种设备 可将来自 2 个输出 HDMI DVI VGA 或任何其他类型的图像输出 的图像合并为屏幕上显示的最终图像 输出可以是相同类型 例如 2 个 HDMI 或不同类型 任何有效的都可以 如果不清楚 这里有一
  • ffmpeg 将 m4s 转换为 mp4

    我正在研究 DASH 试图为最终用户优化 QoE 我有一个视频 并使用 ffmpeg 将其编码为不同的比特率 一切都很好 并且可以使用 dash 播放该视频 我想要的是将用户收到的片段合并为一个 m4 并将该 m4 转换为 mp4 我在 f
  • OpenCV:处理每一帧

    我想使用 OpenCV 编写一个跨平台应用程序进行视频捕获 在所有示例中 我发现来自相机的帧是使用抓取功能进行处理并等待一段时间 我想处理序列中的每一帧 我想定义自己的回调函数 每次当一个新帧准备好处理时都会执行该函数 例如直播对于 Win
  • Android 应用程序中通过 VideoView 将正在播放的视频静音

    我想在我的 Android 应用程序中将 VideoView 正在播放的视频静音 我在 VideoView 类中找不到任何方法来执行此操作 知道如何做到这一点吗 我在 MediaPlayer 类中找到了一个方法 setVolume 但我无法
  • 在 Chrome 中使用 animate.css 时出现全屏视频问题

    我有一个页面 其中包含使用视频标签的视频 另外 我的页面使用 animate css 向我的元素添加一些动画 问题是 当我在 animate css 中使用样式时 我的视频无法正确全屏显示 这是我的页面的示例 div div class g
  • 使用 MP4 编码在 Flash 中流式传输网络摄像头视频

    我正在开发的 Flash 应用程序的功能之一是能够将网络摄像头流式传输给其他人 我们只是使用 Flash 中的内置网络摄像头支持并通过 FMS 发送它 有些人要求更高质量的视频 但我们已经在 Flash 中使用了最高质量设置 将质量设置为
  • JavaScript 和 HTML - 视频屏幕退出后停止背景声音

    我想停止视频播放视频背景声音或在退出视频屏幕后停止声音 全屏 现在的错误是退出视频屏幕后视频背景声音仍在播放 所以我只想删除视频背景声音 这是我的视频
  • 如何进行时间码计算?

    我有一个关于计算时间码增量的问题 我从包含时间码格式的电影文件中读取元数据HH MM SS FF FF 框架 00 gt 23例如 所以它就像00 to framerate 1 所以我得到一些数据 比如15 41 08 02从另一个参考文件
  • 为什么 Windows 只允许一个应用程序访问网络摄像头? [关闭]

    Closed 这个问题是无关 help closed questions 目前不接受答案 我一直在尝试用 C 制作一个示例网络摄像头应用程序 我发现该应用程序无法同时运行 Skype 或 Oovoo 或任何其他应用程序运行 反之亦然 为什么
  • 如何使用OpenGL数组纹理?

    我正在尝试在OpenGL中使用精灵表 通过数组纹理实现它这就是我加载纹理的方式 QImage image image load C QtProjects project images spritesheet png png const un
  • OpenCV 读取视频文件时内存不足

    此示例从文件中读取视频cv2 VideoCapture在 python OpenCV 中内存不足 import cv2 cap cv2 VideoCapture file mp4 while True ret frame cap read
  • 从视频创建缩略图 - 提高速度性能 - AVAsset - iPhone [重复]

    这个问题在这里已经有答案了 我正在使用基于以下线程中的代码的代码来生成视频缩略图 从 iPhone SDK 中的视频 URL 或数据获取缩略图 https stackoverflow com questions 1347562 gettin
  • 允许使用 SurfaceTexture 在 GLSurfaceView 渲染器中进行多通道渲染

    我正在显示视频GLSurfaceView使用需要连续应用多个着色器的自定义渲染器 目前 它可以成功地使用一个着色器 但我不确定如何扩展渲染管道以连续应用多个着色器 我知道有一些关于应用多个着色器的示例 使用FrameBuffers and
  • 确定 SceneKit 中 SKVideoNode 的视频大小/长宽比

    如何从 AVPlayer 获取视频的视频大小来设置节点的几何大小 例如 我有一个具有宽度和高度的 SCNPlane let planeGeo SCNPlane width 5 height 5 所以现在我实例化我的视频播放器 let vid
  • 在 IOS 10 beta 7 (Safari) 中使用 webGL 渲染视频 - 显示奇怪的紫色

    我正在 webGL 中渲染视频 通过传递Video对象作为源texImage2D 这在所有平台 支持 webGL 中都很好用 但是在 IOS 10 beta 7 的 Safari 中 它以奇怪的颜色渲染 在以前的 IOS 版本中看起来还不错
  • 使用.NET技术录制屏幕视频[关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 有没有一种方法可以使用 NET 技术来录制屏幕 无论是桌面还是窗口 我的目标是免费的 我喜欢小型 低
  • 如何在 FFMPEG 中的多个视频之间创建交叉淡入淡出过渡?

    我目前正在通过 FFMPEG 循环播放带有音频的 MP4 视频 这是代码 del intermediate1 ts del f txt echo file intermediate1 ts gt f txt echo file interm

随机推荐

  • Python实现文件编码转换GB2312、GBK、UTF-8

    Python实现文件编码转换GB2312 GBK UTF 8 1 查看文件编码格式 import chardet filename flash c with open filename rb as f data f read encodin
  • [BugKu Web]ez_serialize

    本writeup已经在bugku开放 根据题意 显然是一道JAVA反序列化的题 关于JAVA反序列化漏洞的成因 参见博客https zhuanlan zhihu com p 422314689 此处只说明解题思路 重复开启场景已经没金币了
  • flex布局,子元素设置flex: 1和nowrap,内容长度超出盒子

    解决方法 子元素设置宽度即可 flex 1 width 0 或者 flex 1 min width 0
  • Springboot 项目启动出现 Mysql Lock wait timeout exceeded; try restarting transaction 错误

    一 查询 你的当前数据是否有 Sleep 的事务 执行 sql 检查 在你的项目停止或关闭后检查 show full PROCESSLIST 如果有执行 kill 杀掉 kill id kill 3009 二 查询是否存在挂起的锁 sele
  • pc虚拟服务器,基于虚拟服务器的分布式PC共享平台设计及实现

    摘要 随着云计算等技术的不断发展 C S架构的计算能力在慢慢地向服务器端倾斜 公有云 私有云等产品的出现 代表着人们访问应用程序时不再依赖于传统PC而是借助瘦客户机等连接网络的设备 本文旨在构建基于虚拟服务器的分布式PC共享平台 将桌面虚拟
  • 毕业设计-基于生成对抗网络的图像风格迁移

    目录 前言 课题背景和意义 实现技术思路 一 相关工作 二 基于生成对抗网络的风格迁移模型 三 实验与结果分析 四 总结 实现效果图样例 最后 前言 大四是整个大学期间最忙碌的时光 一边要忙着备考或实习为毕业后面临的就业升学做准备 一边要为
  • 计算机算法与程序设计 第一章 编程作业

    返回 所有测验 作业和考试都在2020年12月30日23点截止 请及时完成 编程作业题可以多次提交 取最高分作为本题成绩 依照学术诚信条款 我保证此作业是本人独立完成的 温馨提示 1 本次作业属于Online Judge题目 提交后由系统即
  • 解决Windows系统缺少comres.dll文件无法启动程序问题

    其实很多用户玩单机游戏或者安装软件的时候就出现过这种问题 如果是新手第一时间会认为是软件或游戏出错了 其实并不是这样 其主要原因就是你电脑系统的该dll文件丢失了或没有安装一些系统软件平台所需要的动态链接库 这时你可以下载这个comres
  • 类的静态成员变量初始化时间

    首先先搞明白 声明 定义 初始化 类的静态成员变量在类内声明 可以多次声明 类的静态成员必须在类外定义 定义就是给变量分配内存 初始化就是给一个变量赋初值 内置类型通常定义时默认初始化 类静态成员变量在main函数执行前完成初始化 有静态初
  • buck拓扑原理及仿真

    buck基本拓扑结构 开关管ON 电源向负载电阻提供电能 电感电流线性增大 变化率 变化量 开关管OFF 电感 电容中能量继续向负载电阻提供电能 电感电流线性减小 变化率 变化量 平衡状态时 由电感伏秒平衡得 推导得 理论电感电流在CCM
  • 快节奏多人在线游戏网络入门系列教程(2):客户端预测与服务器协调

    简介 在上一篇文章中 我们简单介绍了权威服务器的体系 客户端发送交互信息给服务器 服务器周期性的更新游戏状态 然后返回游戏状态给客户端 这个简单体系会导致用户发送命令时和屏幕渲染响应之间的延迟 产生延迟的原因是客户端发送命令给服务器 加上服
  • BIO/NIO/AIO

    IO模型 BIO BIO全称为 Blocking I O 是一种同步阻塞IO 最开始的网络通信就是BIO模型 服务端创建一个ServerSocket 客户端创建一个 Socket 去连接服务端 这样客户端与服务端便可以进行通信了 产生的问题
  • Mybatis中针对数据库日期JdbcType设置

    Mybatis中针对数据库日期JdbcType设置 在学习Mysql的时候 我们知道数据库类型有date datatime time类型 在用Mybatis进行插入数据的时候 我们实体一般都是直接指定java util Date类型 为了确
  • 机器学习中的相似性度量

    https www cnblogs com heaad archive 2011 03 08 1977733 html 1 欧氏距离 曼哈顿距离 切比雪夫距离 闵可夫斯基距离 标准化欧氏距离 马氏距离 夹角余弦 汉明距离 杰卡德距离 杰卡德
  • 菜鸟入门HTML

    标题HTML 一 1 单标签 一般单独完成某一功能的标签都为单标签 link 导入图片或css或其他资源 例 img src路径 插入一个图片到网页中 例 img src title 123 在这里插入图片描述 https img blog
  • 转:彻底搞定期货穿透式CTP API接入

    中信期货看穿式监管认证操作指南 CTP系统 https www citicsf com static download soft E4 B8 AD E4 BF A1 E6 9C 9F E8 B4 A7 E7 9C 8B E7 A9 BF E
  • NTSC和PAL制同步信号模拟输出

    NTSC和PAL制同步信号模拟输出 原由 由于我想输出一个NTSC制和PAL制的同步黑场 只需要输出同步信号 之后输出rgb信号给ADV 7123 后输出到显示屏 下面是我的心路历程和知识总结 一 了解NTSC和PAL PAL 电视标准 每
  • kinect2.0视角范围和距离远近

    本文章由cartzhang编写 转载请注明出处 所有权利保留 文章链接 http blog csdn net cartzhang article details 44588097 作者 cartzhang Kinect 摄像头范围介绍和玩家
  • 马踏棋盘求----全部解

    标题 运用栈和回溯法求马踏棋盘的全部解 回溯法的写法参考 数据结构 严蔚敏 的迷宫求解 感谢我的队友 汪汪汪 他与求一个解不同之处在于 当我们求到一个解之后 这个程序却会告诉计算机 啊 这不是我们想要的解 我们继续吧 于是 傻傻的计算机就信
  • D3D资源管理

    摘要 受管贴图 Managed textures 也就是我们通常所谓的 自动管理贴图 在DX6中首次被引入 经过一系列的改进和增强 在DX9中自动管理的资源类型增加到贴图 顶点缓冲 顶点索引缓冲 所有这些资源使用统一的公共接口 通过使用D3