PDA

View Full Version : OpenGL and IDXGISwapChain1 for buffer swaps



MalcolmB
10-20-2014, 01:36 PM
Has anyone tried to use a IDXGISwapChain1 to do buffer swaps instead of SwapBuffers()? I'm not sure if it's possible but since there is a new IDXGIFactory2::CreateSwapChainForHwnd (http://msdn.microsoft.com/en-us/library/windows/desktop/hh404557%28v=vs.85%29.aspx), it seems possible in theory. Also since the swap chain can work on GDI windows (and since SwapBuffers() is also a GDI function), it also seems possible. Yet another reason I think it may be possible is that SwapBuffers() seems to work fine if called from a thread that doesn't even have an OpenGL context, so the swapping may be disconnected from GL enough for this to be functional.
When I tried I was able to create the swap chain successfully but the Present1() call just clears the window to black and never showed my content.
The reason I'm interested in doing this is to have access to the better documented sync interval behavior outlined for Present1(). wglSwapInterval() has some bugs I'm running into on Nvidia drivers (submitted to Nvidia) that I'd like to work around if I could.
Also perhaps this could fix the tearing/corruption issue that happens on Windows 7/8 depending on Aero/Window state.

The code I'm using current is this:



auto dev = getDXDevice();

IDXGIDevice2 * pDXGIDevice;
HRESULT hr = dev->QueryInterface(__uuidof(IDXGIDevice2), (void **)&pDXGIDevice);

IDXGIAdapter * pDXGIAdapter;
hr = pDXGIDevice->GetParent(__uuidof(IDXGIAdapter), (void **)&pDXGIAdapter);

IDXGIFactory2 *fact;
pDXGIAdapter->GetParent(__uuidof(IDXGIFactory2), (void **)&fact);

DXGI_SWAP_CHAIN_DESC1 desc;
memset(&desc, 0, sizeof(desc));
desc.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
desc.SampleDesc.Count = 1;
desc.SampleDesc.Quality = 0;
desc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT | DXGI_USAGE_BACK_BUFFER;
desc.BufferCount = 2;
desc.Scaling = DXGI_SCALING_STRETCH;
desc.SwapEffect = DXGI_SWAP_EFFECT_SEQUENTIAL;
desc.AlphaMode = DXGI_ALPHA_MODE_IGNORE;
desc.Flags = DXGI_SWAP_CHAIN_FLAG_GDI_COMPATIBLE;

hr = fact->CreateSwapChainForHwnd(dev, hwnd,
&desc,
nullptr, // fullscreen
nullptr, // output restriction
&theSwapChain);


and then the buffer swap is gone with glFinish() called by a call to theSwapChian->Present1().

Maybe this isn't possible, just thought I'd raise the idea.

Dark Photon
10-22-2014, 06:43 AM
wglSwapInterval() has some bugs I'm running into on Nvidia drivers (submitted to Nvidia) that I'd like to work around if I could.
Also perhaps this could fix the tearing/corruption issue that happens on Windows 7/8 depending on Aero/Window state.

Could you outline what bugs you are seeing? I'd be interested in them. Also which NVidia driver version are you running? --Thanks.

MalcolmB
10-22-2014, 12:15 PM
The issue I'm trying to solve is that often I need to show 30hz content on 60hz monitors. If I call SwapBuffers() 30 times a second there is no guarantee that each frame will be shown for 2 refreshes, resulting in visual stutters when content is shown for 16ms, 33 or 49ms arbitrarily.
So I call wglSwapInterval(2) to solve this. It works sometimes and other times it does not. It's unclear what cases cause it to stop working and when it does works. For example one case I was able to produce had it working if the window covered the entire desktop (1920x1200), but if I made it 1920x1199 it would look stuttery. I've tried this with 333.11 and newer drivers.

Dark Photon
10-24-2014, 06:45 AM
I see -- thanks.