I recently changed graphics card for a AMD RX580 which is quite old, but a bit better than the NVidia 1050 I had. I'm on Windows 10.
Since that change, I noticed an issue with my OpenGL applications which is that when I'm in fullscreen and try to alt tab to another application, I have a black flash (which looks like windows or the graphics driver is switching mode). It's OK for a game where I don't often alt tab, but I have the same issue with 4coder where I alt tab often and it got pretty annoying.
After searching on the web I found somewhere that using a dxgi swap chain could solve that issue. Supposedly setting OpenGL tripple buffering in the AMD driver should make OpenGL application use a DXGI swap chain, but I don't see any change in my case.
I then found this github: https://github.com/pmttavara/OpenGL-on-DXGI1.3
And the sample is working, but it creates several copies of different buffer and has a somewhat involved setup.
The page contained a gist from mmozeiko: https://gist.github.com/mmozeiko/c99f9891ce723234854f0919bfd88eae#file-dxgl_flip-c
Which seemed simple enough, but after trying it, it doesn't work when I try to resize the window, and when I added IDXGIDebug_ReportLiveObjects( dxgi_debug, DXGI_DEBUG_ALL, DXGI_DEBUG_RLO_ALL );
it reported a lot of texture reference not released (in the output window of the debugger).
So I tried to change the code to address the reference leak, and fix the error. The leak was fixed by not creating the render target view each frame, only create it when the window is resized (although it's probably a symptom of the other issue).
But the error still happen when I resize the window. The error message is:
DXGI ERROR: IDXGISwapChain::ResizeBuffers: Swapchain cannot be resized unless all outstanding buffer references have been released.
When I call IDXGIDebug_ReportLiveObjects
it shows that there are 3 buffers still active at the time I call ResizeBuffers
, and not matter what I tried in the past few days, I couldn't find a solution.
My understanding is that there are 2 buffer for color (back and front buffer ?) and 1 for the depth stencil. The 2 color buffer reference "appear" when I call SwapChain_GetBuffer
, and the depth stencil is created manually.
At some point I stopped using the depth stencil to make it simpler. With that out, I managed to make it work but I think what I do is a bad idea: I release the color buffer twice. That works and I was able to confirm that I had not black flash when alt tabbing in full screen. The thing that is weird is that when I release only once, the reference count in the report doesn't change.
Also it doesn't work when the depth stencil is present, and I'm not comfortable with releasing the color buffer twice.
Here is the code: https://sisyphe.be/donotdelete/dxgl.zip
It's a modification of mmozeiko gist. At the top of the file there are 2 defines, one to enable the depth stencil buffer, and one to enable the hack of releasing the buffer twice (which is enabled at the moment).
So my questions are:
1 If anyone has a simple fix for the black flash when alt+tabbing on AMD cards in fullscreen OpenGL, I'd like to know.
2 Does anyone knows how to properly release the buffer before resizing the swap chain ?
3 My goal is only to use dxgi to present what OpenGL has rendered. I use glClipControl to flip the OpenGL viewport coordinates so that when DirectX display the buffer it's in the correct orientation. Is there an easier way to use dxgi to display the render of OpenGL ? Or some way to control the OpenGL swap chain ?
4 I want to have a depth buffer in OpenGL, do I need to do the DepthStencil in DirectX ? Or could I just have it has an OpenGL render buffer (I haven't looked at that very much at the moment). So the OpenGL framebuffer would be the color buffer from DirectX but a depth stencil buffer from OpenGL ?
One of the reason I would like it to be simple is that I would like to add it in 4coder and I don't want to complicate a code base shared by other.