美文网首页
【DirectX12笔记】DX12 Do's And Don't

【DirectX12笔记】DX12 Do's And Don't

作者: crossous | 来源:发表于2020-09-09 21:56 被阅读0次

    DX12 Do's And Don'ts

    命令提交-命令列表(CommandList)

    1.将命令交给CmdList不会开始任何工作,只有调用ExecuteCommandList,将CmdList提交给命令队列后才开始在GPU工作
    2.记录命令是CPU密集型操作,CmdList不是线程自由对象,最好将工作均匀分配在各个线程中,一个CmdList只在一个线程中访问(CmdQueue好像是线程安全的)。
    3.建立和重置命令列表会产生一定成本,Fence会强制拆分CmdList(用于查询FenceValue?)
    4...后面是Bundle的,我暂时对这方面没什么了解

    管线状态对象(PSO)

    1.PSO最好异步创建【没什么感受】
    2.避免运行时的PSO编译,这可能导致停顿
    3.尽可能减少PSO之间的状态变化,PSO不一定会映射到GPU上的原子状态变化
    我的理解:可能GPU执行的时候PSO还未完全切换完毕,如果状态变化越小(例如Blend、图元类型、光栅化设置)等越小,出问题的可能性越低。
    //一堆我理解不了的
    4.同一命令队列(CmdQueue)不要再计算(Compute)和图形(Graphics)之间切换,这是很消耗性能的行为
    5.不要打开/关闭曲面细分,这也是消耗性能的行为

    根签名(Root Signature)

    1.CBV不需要用描述符表索引,这意味着不需要描述符堆(Descriptor Heap)来储存。
    2.CBV、SRV、UAV值缓存在CPU中,当检测到更改时再更改根签名中的内容(龙书中是用Dirty来对三缓冲结构程序进行常量缓冲区更新)
    3.限制CBV、SRV、UAV的着色器可见阶段
    体现在slotRootParameter的InitAsDescriptorTable方法第三个参数设置可见性,本人是在编译着色器后,用反射检查着色器可见阶段。
    4.最小化根签名更改次数
    原文提到,问题不在于根签名(RS)的更改,而是在更改之后,通常要初始化根签名。
    由于不确定每个着色器的根签名是否一致,每个物体在渲染之前都要设置一下根签名,而更改RS同时也意味着CommandList的PSO要切换
    【不同Shader的RS可能一致吗?或许有可能,但我感觉机会很小,根签名与对各View的引用顺序、着色器可见性有关,或许对着色器约定俗称,前三个是PerPass、PerObject、PerMaterial的CBV,再设置其他数据,能提高不同Shader的RS相同的几率,但这依旧只是一个方案】
    以后在渲染前,可能要对物体渲染次序做排序或归类,用同样Shader的物体同时渲染。
    5.不要将更新频率不同的CBV放到一个描述符表中
    我的理解是:这里提到,在Haswell这种平台下,更新描述符表中一个CBV会导致表中所有的CBV进行更新。
    6.不要再同一着色器阶段同时设置访问和拒绝标志,否则,除非访问标志是D3D12_SHADER_VISIBILITY_ALL,拒绝(deny)标志是不会生效的。
    这个……属于编程失误了吧?
    7.不要将常量SRV、UAV直接设置在RS中,除非有很多使用它们的绘制(draw)、调度(dispatch)
    看龙书以及别人的代码,SRV一般都是用描述符表存的
    8.更改RS后,不要使资源绑定保持未定义状态,切换RS会删除、清除之前根签名的资源绑定。

    分配器(Allocator)

    1.重用命令分配器(CmdAlloc)和命令列表(CmdList),每次绘制调用数量最好相似,预热后分配速度会更快。
    这样的话,命令列表和分配器最好不要池化了。
    2.一帧调用之前,分配器先调用Reset方法,否则分配器会持续增长,直到耗尽内存
    3.不要总是创建分配器,而是重用分配器
    4.不要释放(Release)/重用(Reset)仍在使用的分配器,这是非法的(一般用围栏值确定当前帧渲染完毕再Reset)

    相关文章

      网友评论

          本文标题:【DirectX12笔记】DX12 Do's And Don't

          本文链接:https://www.haomeiwen.com/subject/sieyektx.html