1
\$\begingroup\$

Sorry for the long question :D

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

\$\endgroup\$
3
\$\begingroup\$

Yes, you can use that code to update a Unity RenderTexture (not simply a Texture2D). You need to make sure that code executes on the render thread. To do that, make sure you only call it in response to the GL.IssuePluginEvent (which will translate to the C++ function UnityRenderEvent).

\$\endgroup\$
  • \$\begingroup\$ Thank you so much CodingJar. I just got back to the problem and still needed the answer. I'll try it out as soon as I can. \$\endgroup\$ – DuoPegla Sep 7 '15 at 8:34

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.