GetDC/ReleaseDC的IDXGISurface1线程安全/同步规则

IDXGISurface1 thread-safety/synchronization rules for GetDC/ReleaseDC?

本文关键字:安全 同步 规则 线程 IDXGISurface1 ReleaseDC GetDC      更新时间:2023-10-16

对于使用D3D11_RESOURCE_MISC_GDI_COMPATIBLE创建的纹理,IDXGISurface1 GetDC/ReleaseDC的线程安全规则是什么?

我是否可以在另一个线程上与GetDCReleaseDC之间的ID3D11DeviceID3D11DeviceContext交互,而不会由于隐式同步而导致数据争用或阻塞?还是为了避免GPU空转,我被迫为执行GDI渲染的线程创建一个单独的D3D11Device,然后通过复制到D3D11_RESOURCE_MISC_SHARED_KEYED_MUTEX将其传输回"主"D3D11Device

即以下内容有效吗?

thread 1:
D3D11Device::CreateTexture2D // Create texture 1
IDXGISurface1::GetDC // Get DC for texture 1
... // Draw to texture1 using GDI
IDXGISurtface1::ReleaseDC // Release DC for texture1
thread 2:
// Is this valid if thread 1 is drawing using GDI?
D3D11DeviceContext::OMSetRenderTargets
D3D11DeviceContext::Draw // Draw texture2. 

MSDN的以下两个要点似乎表明,这个线程不仅不安全,而且在HDC出色的同时,设备的功能也有所降低。

  • 在发出任何新的Direct3D命令之前,必须释放设备(它们指的是HDC)并调用IDXGISurface1::ReleaseDC方法。

  • 如果此方法已经创建了未完成的DC,则此方法将失败。

从DXGISurface获取HDC本质上涉及曲面的父D3D11 DC。D3D11 DC的多线程访问也不受支持。来自此MSDN页面:如果多个线程必须访问单个ID3D11DeviceContext,则它们必须使用一些同步机制,例如关键部分,来同步对该ID3D11Device上下文的访问。

正如你所说,我会尝试在一个单独的线程上准备GDI绘图,但将其呈现到系统内存缓冲区。然后简单地将内容blit到DXGI曲面。

还要注意,这些主题中的大多数涉及即时上下文的行为,D3D11延迟上下文可能具有不同的行为。