1

这篇文章说:

ID3D11DeviceContext 方法(除了那些存在于 ID3D11DeviceChild 上的方法)不是自由线程的,也就是说,它们需要单线程。一次只有一个线程可以安全地调用它的任何方法(Draw、Copy、Map 等)。

我想知道我是否可以让 COMID3D11DeviceContext为我做同步。

假设我这样做(在简化代码中):

CoInitializeEx( NULL, COINIT_APARTMENTTHREADED );
// Create D3D11Device
CComPtr<ID3D11DeviceContext> pD3D11DeviceContext;
pD3D11Device->GetImmediateContext(&pD3D11DeviceContext);

然后我要么编组它:

IStream* pStreamD3D11DeviceContext = NULL;
CComPtr<IUnknown> pUnknownD3D11DeviceContext;
pD3D11DeviceContext->QueryInterface(IID_PPV_ARGS(&pUnknownD3D11DeviceContext));
::CoMarshalInterThreadInterfaceInStream( __uuidof(ID3D11DeviceContext), pUnknownD3D11DeviceContext, &pStreamD3D11DeviceContext );

或者我们一个 GIT 表:

CComPtr<IGlobalInterfaceTable> pIGlobalInterfaceTable;
::CoCreateInstance( CLSID_StdGlobalInterfaceTable, NULL, CLSCTX_INPROC_SERVER, IID_IGlobalInterfaceTable, (void **)&pIGlobalInterfaceTable );
CComPtr<IUnknown> pUnknownD3D11DeviceContext;
DWORD    dwCookieD3D11DeviceContext = 0;
pD3D11DeviceContext->QueryInterface(IID_PPV_ARGS(&pUnknownD3D11DeviceContext));
pIGlobalInterfaceTable->RegisterInterfaceInGlobal( pUnknownD3D11DeviceContext, __uuidof(ID3D11DeviceContext), &dwCookieD3D11DeviceContext );

不幸的是,这似乎不起作用。 CoMarshalInterThreadInterfaceInStream返回REGDB_E_IIDNOTREG( 0x80040155, Interface not registered) 并pStreamD3D11DeviceContext保持为 NULL。

GIT 方法更进一步。我得到了 cookie,但是当我尝试在另一个 MTA 线程上使用它时,GetInterfaceFromGlobal 返回 E_INVALIDARG。

CComPtr<ID3D11DeviceContext> pD3D11DeviceContext;
hresult = pIGlobalInterfaceTable->GetInterfaceFromGlobal( dwCookieD3D11DeviceContext, __uuidof(ID3D11DeviceContext), (void**)&pD3D11DeviceContext );

参数GetInterfaceFromGlobal似乎没问题,我测试了将指针返回到原始线程并且它有效。

D3D11DeviceD3D11DeviceContext似乎是不可编组的。显然,我既没有代理 DLL,也没有 d3d11 的类型库。

我错过了什么吗?

谢谢你。

4

0 回答 0