Marshalling D3D11Device and D3D11DeviceContext objects

1

This article says:

The ID3D11DeviceContext methods (except for those that exist on ID3D11DeviceChild) are not free-threaded, that is, they require single threading. Only one thread may safely be calling any of its methods (Draw, Copy, Map, etc.) at a time.

I was wondering if I can make COM do the ID3D11DeviceContext synchronization for me.

Let's say I do this (in simplified code):

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

Then I either marshall it:

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

Or us a GIT table:

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 );

Unfortunately this doesn't seem to work. CoMarshalInterThreadInterfaceInStream returns REGDB_E_IIDNOTREG (0x80040155, Interface not registered) and pStreamD3D11DeviceContext remains NULL.

GIT method goes one step further. I get the cookie, but when I try to use it on another MTA thread, the GetInterfaceFromGlobal returns E_INVALIDARG.

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

The params for GetInterfaceFromGlobal seem okay, I tested getting the pointer back on the original thread and it worked.

The D3D11Device and D3D11DeviceContext appear to be unmarshallable. Obviously I have neither proxy DLL nor a typelib for the d3d11.

Am I missing anything?

Thank you.

c++
multithreading
com
marshalling
direct3d11
asked on Stack Overflow Feb 13, 2014 by vt.

0 Answers

Nobody has answered this question yet.


User contributions licensed under CC BY-SA 3.0