如何判断GPU上的Direct2D任务已执行完成?
判断GPU上Direct2D任务完成的方法
Direct2D的EndDraw是在GPU端异步执行的,若调用该接口后立即执行IMFSinkWriter::WriteSample,会因GPU任务未完成导致设备挂起。要在CPU端确认GPU上的Direct2D任务已完成,可通过ID3D11Fence API实现,具体步骤如下:
步骤1:获取关联的D3D11设备与上下文
Direct2D渲染目标(如ID2D1DCRenderTarget)基于D3D11设备创建,通过QueryInterface从渲染目标获取ID3D11Device,再进一步查询得到ID3D11Device5(创建栅栏需要此版本接口);同时获取对应的ID3D11DeviceContext。
步骤2:创建ID3D11Fence对象
调用ID3D11Device5::CreateFence,将初始栅栏值设为0,根据需求指定标志位(如不需要跨进程共享则无需D3D11_FENCE_FLAG_SHARED)。
步骤3:在EndDraw后插入栅栏信号
完成ID2D1RenderTarget::EndDraw调用后,调用ID3D11DeviceContext::Signal,传入创建好的栅栏对象和一个递增的信号值(例如每次调用时用当前已完成值+1),以此标记Direct2D任务的结束节点。
步骤4:CPU端等待任务完成
- 创建一个手动重置的事件对象(通过
CreateEvent); - 调用
ID3D11Fence::SetEventOnCompletion,传入目标信号值和事件对象,GPU完成该信号对应的任务后会触发此事件; - 调用
WaitForSingleObject等待事件触发,此时CPU会阻塞直到GPU完成所有前置Direct2D任务。
注意事项
- 兼容性:
ID3D11Device5仅在Windows 10 1709及以上版本支持,需做好版本判断; - 事件管理:每次等待完成后需重置事件对象,避免下次等待误触发;
- 信号值唯一性:确保每次
Signal使用的信号值递增,防止因重复值导致的判断错误。
内容的提问来源于stack exchange,提问作者Tom Huntington
相关产品推荐
相关产品推荐

