cancel
Showing results for 
Search instead for 
Did you mean: 

wglDXRegisterObjectNV returns 0 but no error ( NV_DX_interop2 )

knchaffin
Explorer
Has anyone successfully added NV_DX_interop2 functionality to a PC Win10 OVR SDK app with NVIDIA GTX 1080 GPU?  Just to be clear, my goal is to be able to execute arbitrary GL code and have it
write to the DX eye render targets, with the proper wglDXLockObjectsNV()
and wglDXUnlockObjectsNV() surrounds.


The problem I am having is that when I call

gl_handles[0] = wglDXRegisterObjectNV(gl_handleD3D, dxColorbuffer,  gl_names[0], GL_RENDERBUFFER,  WGL_ACCESS_READ_WRITE_NV);

the handle is set to 0, but there is no error detected by GetLastError();  So, I have 2 renderbuffer objects, color and depth, that are derived from the OVR eye render targets/buffers.  The dxColorbuffer object appears correct, as does the dxDepthbuffer object.  The call succeeds on the dxDepthbuffer object and sets the handle to a non-null value.

I think I am doing all the required steps correctly, including:

gl_handleD3D = wglDXOpenDeviceNVFunc((void *)((OVR::Render::D3D11::RenderDevice*)pRender)->Device); 
glGenFramebuffers(2, gl_fbonames);
glGenRenderbuffers(2, gl_names);
gl_handles[0] = wglDXRegisterObjectNV(gl_handleD3D, dxColorbuffer, gl_names[0],   GL_RENDERBUFFER,      WGL_ACCESS_READ_WRITE_NV);

... subsequent calls such as glBindFramebuffer(), etc. are present but not shown.

Thanks.












57 REPLIES 57

volgaksoy
Expert Protege
Are you doing the GL to DX conversion in hopes of using OpenGL with the OVR SDK API? Or are you hoping to mix and match GL and DX APIs in your own app? I ask because you can directly use OpenGL with the OVR SDK API without having to jump thru interop hoops.

knchaffin
Explorer
I am hoping to mix and match GL and DX APIs in my own app.  I am aware of the OpenGL support within the OVR SDK API.  I hope I am understanding the difference correctly.  What I am really trying to do is integrate the OVR Avatar SDK into my DX based OVR SDK app.  The Avatar SDK is GL only.  So, I'm trying to jump through a few hoops such that the Avatar SDK API and example code can be used basically unchanged.

knchaffin
Explorer
By the way, my app is a research platform that also includes a stereoscopic video camera mounted on an Arduino robotics turret and controlled via UDP sockets communications 2 way between my app and the Arduino.  So, the HMD poses drive the pan and tilt of the video camera.  A lot is going on in this application.

knchaffin
Explorer
A bit more info...  I am using the pColorTex->Get_ovrTextureSet() to obtain the eye render target 3 member swap chain and then the
ovr_GetTextureSwapChainCurrentIndex(..) function to get the current index and then using (currentIndex+1)%swapChainLength to index into ovr_GetTextureSwapChainBufferDX() to obtain my dxColorBuffer .

Reading other forum conversations leads me to believe that there may be something in the OVR API that prevents NV_DX_interop2 from functioning, such as perhaps the OVR API locking the DX render targets such that GL cannot write to them via interop.  Those conversations are from 3 years back.  Does anyone know if there is such a limitation that would prevent generic GL writing to the shared DX render targets other than using a blit from the GL textures to the DX textures?

Otherwise I am wondering if there is a special setting for the pixel format or attributes when opening the DX/GL device after calling:

wglChoosePixelFormatARBFunc(..)
context = wglCreateContextAttribsARBFunc(hDC, 0, attribs);
wglMakeCurrent(hDC, context);

gl_handleD3D = wglDXOpenDeviceNVFunc((void *)((OVR::Render::D3D11::RenderDevice*)pRender)->Device);

I've been working on this issue for a couple of weeks, to no avail.





Anonymous
Not applicable
bump @volgaksoy (i'm just really curious)

volgaksoy
Expert Protege
The Oculus provided textures internally use GL_TEXTURE_2D instead of GL_RENDERBUFFER type you're using in the wglDXRegisterObjectNV call. So we share the D3D resource over as a texture, and then in GL bind that texture as a framebuffer in GL. Once that's done, you also need to properly lock and unlock the resources when D3D is accessing them using wglDXLockObjectsNV and wglDXUnlockObjectsNV.

However, I think you should side step all of that, and avoid pushing the Oculus SDK provided textures thru the interop. Instead create your own textures and render targets in your own code. Share them between GL and D3D as necessary. Copy the contents of the GL render over to the final Oculus created DX render afterwards. The perf hit to copy over the contents would be minimal. That way you're not trying to make heads or tails of the Oculus SDK's textures.

knchaffin
Explorer
Thank you very much for your suggestions volgaksoy . This gives me a lot to work with 🙂

knchaffin
Explorer
Is there any possibility that Oculus is doing a wglDXRegisterObjectsNV in the background on the application rendertarget swapchain textures?  No matter what I try, wglDXRegisterObjectsNV returns 0 but sets no error.  I think I have seen this behavior before  when I tried to register an object that was already registered.  Of course this also raises the question as to whether Oculus is also doing a wglDXOpenDeviceNVFunc in the background, since wglDXRegisterObjectsNV  requires a DX/GL device handle argument .

It would be nice to know if in fact full NV_DX_interop2 via wglDXOpenDeviceNVFunc is possible with the OVR SDK and runtime.   I'm sure my confusion is related to my ignorance of exactly what Oculus is doing in the runtime DLL, for which source code is not provided (at least that is my understanding).  I see the SDK LibOVR Shim functions for communicating with the DLL, but that's it.

Thanks to anyone who can clarify this.



knchaffin
Explorer
Since I do not fully understand how interop is implemented on the OVR SDK and runtime, I feel that I should mention my framework for my Windows app.

- My app is based on the sample Oculus World Demo app framework.
- The RenderDevice and eye render target objects are declared and defined in the  OculusWorldDemo.h header and the Samples/CommonSrc/Render_D3D11_Device.h headers.

As such, in the OculusWorldDemo.h file, the following are defined:

class OculusWorldDemoApp : public Application                                                                         
{
    ....
   struct RenderTarget                                                                                               
    {                                                                                                                 
        Ptr<Texture>    pColorTex;    
// Texture declared in SamplesCommonSrcRender_D3D11_Device.h    
                                
        Ptr<Texture>    pDepthTex;                                                                                  
    };

// Last render target for eye FOV buffers.                                                                        
    static const int RenderTarget_EyeLast = Rendertarget_BothEyes + 1;                                              
                                                                                                                     
    RenderTarget        RenderTargets[Rendertarget_LAST];                                                            
    RenderTarget*       DrawEyeTargets[Rendertarget_LAST];
    ....
};

@volgaksoy
Is this what you meant when you said I should create my own textures rather than relying on those Oculus provides?  All further actions on the render textures are  done through these pColorTex and pDepthTex.objects.  Should these textures be compatible with the full interop2, if desired?

Thanks