(转载请注明出处)
正如上节末尾所说, 出现了运行时错误:
D3D12 ERROR: ID3D12CommandAllocator::Reset: A command allocator is being reset before previous executions associated with the allocator have completed. [ EXECUTION ERROR #548: COMMAND_ALLOCATOR_SYNC]
就是说要在相关执行完成后才能重置, 在自己的第一印象中, 认为提交呈现(Present)后, 所有的操纵就完成了, 但这样似乎不是这样的, 微软在这里有提到:
Waiting for frame rendering is probably the coarsest way to be certain that the GPU has finished. At a finer grain, you can again use fences
就是说, 等待帧渲染完毕就认为GPU工作完毕了, 这种做法不够好, 最好使用Fence:
好了, 篱笆来了, 路障来了, 微软你不再来个钉刺带?╮( ̄▽ ̄)╭
Fence对应的接口就是ID3D12Fence了,可以利用ID3D12Device::CreateFence创建这个接口, 具体代码就不累述了, 很简单.
这个Fence是以帧为单位的, 可以等待所有针对这一帧的命令.利用ID3D12Fence::SetEventOnCompletion和ID3D12CommandQueue::Signal进行信号操作, 完了之后等待即可, 以帧为单位。
不过还有个ID3D12Fence::Signal, 看来有可能ID3D12CommandQueue::Signal会调用这个方法, 否则这个Fence没有能与命令绑定的方法.
所以大致渲染流程就是:
- Fence -> SetEventOnCompletion
- 执行命令
- 提交呈现
- Queue -> Signal
- WaitForXXXXXXXObject
结合上次, 这次就很简单了. 还有就是我试了下将3放在5后面, 也(貌似?)没问题, 不过根据微软的表述, 还是放在Signal前面.
所附代码下载:
时间: 2024-11-05 23:29:28