We've implemented support for WGL_NV_DX_interop in our application, and I was a bit surprised to see that AMD hardware advertise support for it. Fine, I thought; we get fast-path there as well.
However, as opposed to NVIDIA's implementation, I keep getting an error when I'm trying to register a D3D9 render-target as a GL_RENDERBUFFER. GetLastError() returns ERROR_OPEN_FAILED.
Is there something I can do to get this to work? As-is, our application simply barfs on that error, because it expects wglDXRegisterObjectNV to succeed.
I have attached a small reproduction-case.
Didn't you miss the DirectX share handle?
you pass a pointer as the last parameter of CreateRenderTarget and get the handle back.
then you need the wglDXSetResourceShareHandleNV()
should be as follows (not tested)
device->CreateRenderTarget(1280, 720, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, FALSE, &surface, &DXShareHandle);
wglDXRegisterObjectNV(interopHandleD3D, surface, colorbuffer, GL_RENDERBUFFER, WGL_ACCESS_WRITE_DISCARD_NV);
The extension spec explicitly says "This extension accommodates, but does not require use of WDDM share handles". WDDM share-handles are only needed if sharing between non-GL clients are needed, according to the spec.
However, If I try to pass a WDDM-handle, the extension seems to work. So it seems this is simply an incorrectly implemented extension. That's enough of a work-around for me for now, but I strongly suggest AMD fix the implementation or invent their own simpler version; halfway-working extensions is just disaster waiting to happen.
Actually, it seems to be a second nit that makes this extension useless on AMD for me (unless another work-around is found); The DX side doesn't seem to see updates to the resource done from the GL side. The reproduction case can trivially be extended to show this by adding animation to the GL-code in the while-loop.0
I've tried to change the access mode to read-write, ping-pong between read-write and write-discard, unregister and re-register the object, to no avail.
OK, so I've had to ship a version of our software to our customers with AMD black-listing for the fast-path of our OpenGL -> WPF blitting. I'd really like to avoid having to ship further versions like this, so please get back to me with any updates.
After a lot of testing I was able to get hardware accelerated WGL_NV_DX_interop wrking on AMD cards. I have only tested on 7950 and 7990 cards as of this time. Below is the code I wrote for creating, resizing, and rendering a simple test with animating background clear to test the functionality. My access to AMD cards is very limited. Any feedback on devices that work or don't would be appreciated.
One of the key points that I found was making sure the OpenGL render buffer names are created correctly during resizing operations. WPF performs multiple passes at resizing content so this becomes critical.
This uses a share handle on the DX Render Target, this may not be absolutely needed but given you earlier difficulty I implemented it. I have not tested whether or not this code base will work without the use of resource sharing handles. Hopefully it will help you get your product under full hardware acceleration without the blitting operations from OpenGL to DX surfaces. Tried that and its very slow by comparison to DX_interop usage.