Search Unity

Create a D3D11 RenderTexture with D3D11_RESOURCE_MISC_SHARED ??

Discussion in 'Windows' started by zezba9000, Jan 14, 2016.

  1. zezba9000

    zezba9000

    Joined:
    Sep 28, 2010
    Posts:
    726
    I need to create a "RenderTexture" (aka ID3D11Texture2D) with the "D3D11_RESOURCE_MISC_SHARED" enabled for a native standalone x86/Win32 plugin.

    I'm writing a plugin that creates its own D3D11 device and must copy the native "RenderTexture" to another "ID3D11Texture2D" texture created with my "ID3D11Device" device using "directModeDeviceContext->CopyResource(directModeTexture[surfaceSwap], unityTexture);".

    Is creating a RenderTexture with "D3D11_RESOURCE_MISC_SHARED" possible?
     
  2. zezba9000

    zezba9000

    Joined:
    Sep 28, 2010
    Posts:
    726
    Or if RenderTexture.CreateExternalTexture(..) existed that would be AWESOME!
    As it is now I can't create a native texture in C++ and register it with Unity3D...
     
  3. zezba9000

    zezba9000

    Joined:
    Sep 28, 2010
    Posts:
    726
    Unless I'm mistaken this feature is very much needed in Unity for 3rd party VR HMD devices looking to use the NVAPI DirectMode features.

    Also probably need a Native Unity API "RenderThread" callback that fires before the D3D11 device is created with a "Adapter" override for DirectMode displays. (If such a thing already exists, this would be awesome) [Much better then hooking D3D11 library called.]
     
  4. Tautvydas-Zilys

    Tautvydas-Zilys

    Unity Technologies

    Joined:
    Jul 25, 2013
    Posts:
    6,443
    Hi,

    do you want Unity to render into said texture? Sorry for missing your post on Friday.
     
  5. zezba9000

    zezba9000

    Joined:
    Sep 28, 2010
    Posts:
    726
    Unity is already rendering into "said" texture. The problem is Unity isn't creating that texture with needed native D3D11 flags for VR DirectMode.

    1) The "VR Headset Developers sdk" needs to be initialized in part before the "D3D11CreateDevice" method is invoked.

    2) The "VR Headset Developers sdk" requires that the Unity RenderTexture be created with the "D3D11_RESOURCE_MISC_SHARED" flag.

    The SDK being used that supports DirectMode is located here: https://developer.nvidia.com/virtual-reality-development

    #1 Could be solved by hooking D3D11 method calls (don't want to do this as its a hack).
    #1 Should be solved by Unity simply adding in a native 'C' callback maybe like: "void UNITY_INTERFACE_EXPORT UNITY_INTERFACE_API_PreInit()". That would get called before Unity calls "D3D11CreateDevice".

    #2 Could be solved by adding in the method "RenderTexture.CreateExternalTexture(..)" or by adding in constructor args for the "RenderTexture" that enable the "D3D11_RESOURCE_MISC_SHARED" flag. (CreateExternalTexture in the RenderTexture would be the best approach I think).

    Then in #2 (CreateExternalTexture) the native resource view could be created by Unity and only the texture created by me.
     
  6. Tautvydas-Zilys

    Tautvydas-Zilys

    Unity Technologies

    Joined:
    Jul 25, 2013
    Posts:
    6,443
    Regarding #1, there is a "-gpu" flag you can pass as a command line parameter to Unity, which will then create D3D11 device using the IDXGIDevice that comes from the specified index.

    Regarding #2, it would totally make sense for us to add such API, however, if we start implementing it today, it will probably be too late for you, so I suggest we look for a workaround. How about you pass renderTexture.GetNativeTexturePtr() to native code, in there, do a copy texture to your own texture which is created with D3D11_RESOURCE_MISC_SHARED flag using unity's device context and then finally copy it to yet another texture using your directMode device context? It might have a little bit of performance overhead, but I think it shouldn't impact you.

    Finally, are you developing for a VR device for which Unity has no native support? It seems you never mentioned it.
     
  7. zezba9000

    zezba9000

    Joined:
    Sep 28, 2010
    Posts:
    726
    For #1 and DirectMode its not so much a GPU index and rather a IDXGIAdapter that is created by the NVAPI that in turn Unity needs to pass into the D3D11CreateDevice method. I have a single GPU I'm testing with. (Am I misunderstanding?).

    For #2 I already have ExtendedMode working and am not sure using DirectMode in such a way as you suggest would have any performance benefit we are looking for. Also DirectMode wont work unless the D3D11 device is created with the IDXGIAdapter that comes from the NVAPI to my knowledge.

    To answer your question, yes I'm working for VRStudios and adding Extended / Direct modes to Unity / UE4 for our HMD. So far Unity in the state it is doesn't seem to support 3rd party HMD's with DirectMode support via the NVAPI. I don't think I will have any problem with this for UE4 as it has options to create RenderTargets with the "D3D11_RESOURCE_MISC_SHARED" option and we can always integrate NVAPI features into the engine if they don't already exist for DirectMode initialization.

    Either way, for now Extended mode is ok in Unity but it would be nice if some more native standalone plugin features existed that allowed for the IDXGIAdapter Unity is using to be overloaded.
     
  8. Tautvydas-Zilys

    Tautvydas-Zilys

    Unity Technologies

    Joined:
    Jul 25, 2013
    Posts:
    6,443
    Yea, unfortunately there doesn't seem to be a way to achieve this right now using our plugin interface at this time :/. We'll be looking into adding this functionality in the future, but I can't give any concrete promises of when it's going to be done.
     
    exon101 and zezba9000 like this.
  9. exon101

    exon101

    Joined:
    Apr 22, 2016
    Posts:
    1
    Hi,
    What is the state on this?
     
  10. Varaughe

    Varaughe

    Joined:
    Apr 22, 2013
    Posts:
    21
    Here is a video example , where a plugin creates its own device context (it's of the separate window from Unity) and gets the RenderTexture from Unity and display it in its own window. It's working for OSX(OpenGL) and Window(Direct3d 11). While for openGL the texture is shared between the contexts, for Direct3d11 , as Tautvydas has said, the solution was to create another texture(with that sharing flag) in the Unity's device context and copy (GPU copy) inside it the Unity's texture.
     
    zezba9000 likes this.
  11. zezba9000

    zezba9000

    Joined:
    Sep 28, 2010
    Posts:
    726
    Good post, although I have this mode running with the Unity's device context now and normally we use DirectMode anyway.
     
  12. kk_sun

    kk_sun

    Joined:
    Jun 7, 2017
    Posts:
    2
    hi, did you resolve the problem, i have met this problem too, so can you provide some resource to help me?
     
  13. kk_sun

    kk_sun

    Joined:
    Jun 7, 2017
    Posts:
    2
    hi, the example is what i need. Can you provide the source code of the example, that will be helpful
     
  14. tabulatouch

    tabulatouch

    Joined:
    Mar 12, 2015
    Posts:
    10
    Hello @zezba9000, i would be interested too in having the minimal code to share a D3D11 rendertexture, i am trying to show it in another win32 window.
    Thank you!