我目前正在为DirectX12编写自己的图形框架(我已经为个人游戏引擎编写了几个DirectX 11框架),我目前正在trying to copy the methods used in the recent Hitman game进行资源绑定。
我对处理SRV / CBV / UAV堆的每对象资源绑定的最佳方法感到困惑。我看过几个GDC演示文稿,他们似乎都对此有所了解。
一次只能绑定1个SRV / CBV / UAV堆,并且通过强制刷新,在命令列表中间切换当前绑定的堆可能会对某些硬件的性能造成不利影响。因此,使用新描述符处理堆更新的最佳方法是什么?对我来说,似乎每个命令列表都会:
SetGraphicsRootDescriptorTable
混合的绘制调用,以便在当前描述符堆中移动。话虽如此,网上的几个消息来源(including another SO post)建议使用一个大的SRV / CBV / UAV堆,并使用CPU可见的堆复制到其中。我假设他们没有尝试使用异步CopyDescriptors
,而是CopyBufferRegion
。我尝试使用CopyBufferRegion
更新每个对象的数据,但对我来说,D3D12_RESOURCE_STATE_VERTEX_AND_CONSTANT_BUFFER
和D3D12_RESOURCE_STATE_COPY_DEST
之间的转换效果似乎不佳。我误会了什么吗?任何清晰度都将不胜感激。
答案 0 :(得分:1)
CopyDescriptors
不是异步的,它是CPU上的一个CPU操作。它可以在为volatile列表执行命令列表之前的任何时候发生(在记录使用它的命令列表操作之后),或者必须在静态描述符(root signature 1.1)的使用时准备好。
通常的方法是拥有一个大的描述符堆,保留静态描述符的一部分,然后将其余部分用作环形缓冲区,根据需要分配描述符表偏移量以复制并使用所需的描述符进行任何绘制/计算操作。
CopyBufferRegion
在这里没有任何关系,请记住,映射缓冲区也是一个立即操作,因此你也可以为每个objet常量缓冲区缓冲一大块内存,然后循环进入它。唯一的事情是你需要确保在它们可能仍在使用时不要覆盖内存或描述符,所以你必须围栏以防止这种情况。