如何高效更新Direcx11的各种资源与状态
在DX9时代,很多渲染瓶颈就出现在状态与资源的更新,大量本该简化的Draw调用。虽然DX10后对draw进行了一些优化,但是还不足以让你可以忽略draw的调用方式与次数。我们应该在应用程序的调试版本中恰当使用debug runtime,根据debugRT提供的性能警告来优化程序。
为什么说draw调用的方式很影响性能呢?因为每当你调用一次draw,都会牵一发而动全身,影响到其他状态的更新。一般draw都会引起如下状态的变动:
1.const buffer的更新。
2.资源的变化(顶点缓冲,索引缓冲,纹理等等)。
3.InputLayout的变化。
Constant Buffer
常量缓冲是保存shader中常量的地方。可以用Map()/Unmap()或者Undatesubresource()来更新其中的数据。管线中的每个shader步骤,有的资料说共有16个可用cb,但是我参考MSDN发现SetVertexShaderConstant的startSlot最多只能设置D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT 个,而这个值在我的dx sdk中为14,也就是只能设置13个cb而已。在DX9中你可以通过SetXXShaderConstantX方法单独更新数据,但是DX10后每次更新都是整个cb。如果这个cb非常大,而其中只有很小的部分需要每次call都更新,那么对时间的消耗就很客观。所以比较好的解决方法就是设置多个较小的cb,每次更新就不必更新那些多余用不到的内存。
State
DX10后已经不能像DX9那样单独更新设备状态,因为DX10把所有状态封装到了一个state对象中。该对象是不可改的,所以每次你即使就是要改变state中的一项,你都要从新生成一个新的对象。所以有个方法就是你提前把所有可能用到的state对象创建好,用的时候直接提供,如果不行呢?那咱再想别的方法吧- -!
Shader Linkage
DX9是基于语义(semantic)的。DX10后是基于地址偏移的。这就导致一个限制,数据在shader中的传输不能乱序,必须按照顺序来,但是中间可以却某些变量。同时CreateInputLayout会导致一个验证“动作”的发生,所以不推荐你实时动态生成InputLayout。
Resource Update
posted on 2012-04-01 17:26 Meta.Grfx 阅读(1544) 评论(0) 编辑 收藏 举报
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· DeepSeek如何颠覆传统软件测试?测试工程师会被淘汰吗?