tl;dr version :) Is it possible to update DirectX 11 textures created in Unity asynchronously in a 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 :D