Sorry for the long question
tl;dr version Is it possible to update DirectX 11 textures asynchronously in native plugin (C++)?
I’ve written a plugin that retrieves data from Kinect.
Currently, color stream data is written to a texture created by Unity in a separate thread in the plugin using DirectX 9 as shown in the example below.
D3DLOCKED_RECT lockedRectangle;
colorFrameTextureDX9->LockRect(0, &lockedRectangle, NULL, 0);
memcpy(lockedRectangle.pBits, colorFrameMat.data, colorFrameMat.total() * colorFrameMat.channels());
colorFrameTextureDX9->UnlockRect(0);
With DX9 this works beautifully. As far as I know calling LockRect on a DX9 texture locks the texture data and memcpy after that is thread safe.
Using this code sample from unity I’ve added support for DX11 textures.
ID3D11DeviceContext *ctx = NULL;
device->GetImmediateContext(&ctx); // Device is sent from Unity
D3D11_TEXTURE2D_DESC desc;
colorFrameTextureDX11->GetDesc(&desc);
ctx->UpdateSubresource(colorFrameTextureDX11, 0, NULL, colorFrameMat.data, colorFrameMat.cols * colorFrameMat.channels(), 0);
ctx->Release();
When Unity is run in DX11 mode, this runs perfectly for a few second after which it crashes without error report. I believe the problem is in using UpdateSubresource method which doesn’t lock the texture causing simultaneous access from Unity’s rendering pipeline and plugin thread.
In DX11 documentation I came across the Map/Unmap methods for updating textures which work similarly to LockRect/UnlockRect methods from DX9. However these methods can only be used with DX11 textures created as D3D11_USAGE_DYNAMIC and the texture from Unity is created as D3D11_USAGE_DEFAULT.
Is it possible to change or recreate the texture created in Unity with different usage flags?
Thanks in advance to anyone who even read it all