-
Notifications
You must be signed in to change notification settings - Fork 29
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
ID3D11Device is not thread-safe #26
Comments
Hi, Indeed, this is the typical marshaling error message when you want to pass an object that has no proxy/stub defined between thread. Do you have some more reproducing code? |
Hi,
However, If the _d3dDevice is not created in UI thread, but in another thread instead (uncomment Task.Run above), it will work well. So, is it a expected behavior? |
What framework are you using .NET Framework? .NET Core? 5, 6? |
I used .Net6 |
Ok, I can reproduce, and here is what's happening. First of all, this is not related to DirectN but only to .NET. What happens is ID3D11Device doesn't declare how it behaves with regards to COM threading rules (it's more "nano" COM than full COM), so it's considered MTA by default by .NET. So, for .NET (for the RCW wrapper), it must be marshaled when used from one apartment to another, see here https://docs.microsoft.com/en-us/dotnet/framework/interop/interop-marshalling The problem is ID3D11Device registers no way to be marshaled because... it doesn't need to be! Hence the .NET error (0x80004002) In your reproducing code, since you're creating the device from the main WPF or Winforms thread, the thread that creates the D3D11 device is marked as STA. When you want to use this object from another thread, .NET will try to marshal the device object reference and fails. One solution is to create the device in an MTA thread and keep using it in MTA threads:
Note you won't be able to use the D3D11 device from an STA thread with .NET. |
Thanks, I understood.
so it seems that I cannot use with MTA threads. |
What you should be able to do in this case if it's just for passing objects around, is avoid using interface .NET objects, but use IntPtr variables which are opaque pointers to .NET. So, convert your objects into IntPtr using Marshal.GetIUnknownForObject (or modify interface to get back IntPtr directly) and you should also modify interfaces you use in this case (like ISwapChainPanelNative) so they use IntPtr too. |
Thanks, I will try with that |
See also this for the reasons why it doesn't work (and will never) with COM interop interface : dotnet/runtime#69979 |
Hi,
At first, thanks for creating DirectN and currently, I used DirectN for my project.
As I know ID3D11Device is thread-safe and ID3D11DeviceContext is not, but when I use ID3D11Device to create texture or any buffer in other thread, it meets the error:
I can work around by just using a single thread, but I'd like to use multithread in my case.
Am I missing something on this?
Thank you.
The text was updated successfully, but these errors were encountered: