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

knchaffin
Explorer
Luckily, what I am doing now is just for my own entertainment.  Up until recently I was a university researcher and would pull my hair out trying to keep a research platform and protocol unchanged and functional for the duration of a 5 year federal grant:)  Also, prior to that I worked on commercial 3D software and that was a pain in the butt when something broke due to an OS update usuallly (or a driver update).  And, as I get older, it gets harder and harder to develop bleeding edge systems.  I think you and I may be similar in that we will push past the limits of all systems in trying to do what we envision.

I'm just trying to develop an immersive VR environment in which I can control all of my many music synthesizers and software using the Touch controllers, HMD motion and gesture control.  I want some me-avatars in there with me so I can have a virtual trio 🙂

knchaffin
Explorer
@thewhiteambit

I have everything set up to do the interop in the way that you suggested, but so far when I use DeviceContext->CopyResource(pDst, pDXtexture)
I'm not getting anything rendered.  For testing, I am trying to just copy the empty pDXtexture to the destination without having GL render to it.  My expectation is that it should replace what is in the pDst texture when I do this as I am not using a depth texture.  I have also let the GL code clear the DX texture to an opaque red, to no avail. 

I have tried several pDst textures:

ID3D11Texture2D *pDst;

pDst=Device->BackBuffer, and
Device->BackBufferRT->GetResource(pDst), and

IDXGISwapChain *dxswapchain = Device->SwapChain;
dxswapchain->GetBuffer(0, IID_ID3D11Texture2D, (void **)&pDst);  and

ovrTextureSwapChain oTSC = Device->CurRenderTarget->Get_ovrTextureSet();
ovr_GetTextureSwapChainBufferDX(Session, oTSC, 0, IID_ID3D11Texture2D, (void **)&pDst);  // and other indices 1 and 2

All textures have been confirmed to have the same format and dimensions.

I can call:
Device->Clear(1.0, 0.0, 0.0, 1.0, 1, 1);
to clear the BackBufferRT render target view to opaque red, and that seems to work correctly depending where I call it relative to the 3 "~layers" I am rendering.  Those layers are the Tuscany scene and/or my OVRvision Pro video, the two Touch controllers, and then the interop GL layer.

I'm somewhat at a loss as to what is going on.

What do you use for the CopyResource() destination texture in your interop applications?

I'm sure I am doing something stupid.

Thanks.





thewhiteambit
Adventurer
@knchaffin
I am using CopySubresourceRegion() but just for convenience. CopyResource() also works. Did you manage to use the GL interop textures in DX space (for example as a shader resource while rendering), so you can be sure it's the copy operation failing? Sorry to not be very specific, I implemented this long time ago. But I still remember Copy operations often resulting in only black textures. Maybe you want to fill the destination texture with Blue in advance, so you can see if the read of the copy operation just had it reading wrong and interpret it as Black, or if it does not perform write at all. With CopySubresourceRegion you also can try to copy only a little part in the center then.

knchaffin
Explorer
@volgaksoy
@thewhiteambit

I followed your advice and created my own ID3D11Texture2D render target/shader resource texture of the same format and size of the OVR final render targest (backbuffer, current render target, swap chain members, etc).  I also initialized this DX texture with a checkerboard data pattern in CreateTexture().  For testing purposes I'm trying to make sure I can copy this texture to the OVR final render texture(s) before registering it with GL via the interop functionality, although I have successfully registered it in tests.  I have tried using Context->CopyResource() and Context->CopySubResourceRegion() to every variant of the OVR final render target textures I can think of and verified that those texture formats and dimensions match my DX texture.  The problem is that I never see the checkerboard texture in the final output.  I can successfully clear the render target color to opaque red via:
D3D11Device->Clear(1.0, 0.0, 0.0, 1.0, 0.0, true, false);
which actually ends up clearing D3D11Device->CurrRenderTarget->GetRtv().  So, I made sure that one variant for my CopyResource() is to destination D3D11Device->CurrRenderTarget->GetRtv()->GetResource()

Do either of you know which OVR render target I should copy to and if this should work?  Is there anything else I may need to do to make this work?  This is not an interop issue, but rather an issue of copying pure DX textures to OVR render target textures.

Thanks in advance.







thewhiteambit
Adventurer
@knchaffin
You are probably running into non compatible texture formats for simple blit copying. I know there is somewhere a huge table in DX documentation explaining all compatible texture formats. But I couldn't find them.

Or did you just switch the parameter order on CopyResource? Is uses a counter intuitive way of destination first, then source...

knchaffin
Explorer
@thewhiteambit

I agree that pDst and pSrc argument order is counter intuitive, but I do have them correct.

Both the source and destination textures are
DXGI_FORMAT_R8G8B8A8_UNORM
The DX documentation does not limit the formats that can be used with CopyResource() but rather requires that the formats be "compatible" if a format conversion is required.  E.G.., the texel sizes are 32 bits in both.

thewhiteambit
Adventurer
@knchaffin
just trying to guess why a simple copy can fail. What other flags/parameters do you use for creation of the source and destination texture(s)?

knchaffin
Explorer

ID3D11Texture2D* d3d_colortex_;

const int w = 1600;
const int h = 900;
if (CurrRenderTarget)
{
// w=CurrRenderTarget->GetWidth();
// h=CurrRenderTarget->GetHeight();
debug_trace("CurrRenderTarget w=%d h=%d", w, h);
}
// Create DX surface with dimensions of CurrRenderTarget
D3D11_TEXTURE2D_DESC desc;
ZeroMemory(&desc, sizeof(desc));
desc.Height = h;
desc.Width = w;
desc.MipLevels = 1;
desc.ArraySize = 1;
desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; // A four-component, 32-bit unsigned-normalized-integer format that supports 8 bits per channel including alpha.
desc.SampleDesc.Count = 1;
desc.SampleDesc.Quality = 0;
desc.Usage = D3D11_USAGE_DEFAULT;
desc.BindFlags = 0;
desc.BindFlags |= D3D11_BIND_RENDER_TARGET;
desc.BindFlags |= D3D11_BIND_SHADER_RESOURCE;
desc.CPUAccessFlags = 0;
desc.MiscFlags = 0;

HRESULT hr=deviceD3D11->CreateTexture2D(&desc, NULL, &d3d_colortex_);
@thewhiteambit

The above is my DX texture creation code without the checkerboard data initialization.  Note, I have sRGB turned off in the app.  The OVR rendertargets were created by OVR in the default initialization steps, but with sRGB turned off.  I'm using the OculusWorldDemo app framework, with the /Samples/CommonSrc/Render/Render_D3D11_Device.cpp code included in the VS2017 project..  The DX texture desc values were selected to match obtained desc/format of the OVR render color target (or backbuffer, or swap chain textures as they all are verified to have the same desc/format values)..




thewhiteambit
Adventurer
@knchaffin
The texture desc seems ok. Have you tried if copying works without registering the textures for GL interop?

knchaffin
Explorer
@thewhiteambit
Yes, that is what I am doing.  I tested the interop registration and it succeeds, but I commented that out for testing the resource copying.

I suspect that I am trying to copy to the wrong OVR final render target texture.  For testing I am not using any eye views or RT's but rather just using the single DX texture I created and trying to copy it to the:
ovrD3D11device class object members as defined in CommonSrc/Render_D3D11_Device.h:
Ptr<IDXGISwapChain> SwapChain (GetBuffer(0,)); or
Ptr<ID3D11Texture2D> BackBuffer; or
Ptr<ID3D11RenderTargetView> BackBufferRT; or
Ptr<Texture> CurRenderTarget; ( CurRenderTarget->GetTex()) or          (CurRenderTarget->GetRtv()->GetResource(&ppResource1) 

For each destination test, I make sure the DX texture description matches as the RTV based textures have different width and height than the other textures.

Or the OVR runtime is locking the textures or something similar.