2

I'd like to call IDXGIDevice1::SetMaximumFrameLatency method from my dx12app, for that I need to get a valid IDXGIDevice1 from the current Direct3D 12 device. querying the interface return a E_NOINTERFACE:

IDXGIDevice * pDXGIDevice;
HRESULT hr = myDevice->QueryInterface(__uuidof(IDXGIDevice), (void **)&pDXGIDevice);
assert(hr != S_OK); // returns E_NOINTERFACE

IDXGIDevice1 * pDXGIDevice1;
HRESULT hr1 = myDevice->QueryInterface(__uuidof(IDXGIDevice1), (void **)&pDXGIDevice1);
assert(hr != S_OK);  // returns E_NOINTERFACE 

Not sure if I'm missing something or there is sequence of dxgi logic I need to implement to get a valid IDXGIDevice1 interface.

Would appreciate any hints & thanks in advance! Klip

K Klip
  • 21
  • 1
  • 2

1 Answers1

2

For Direct3D 12, this 'legacy pattern' of obtaining the DXGI factory is not supported, so your code above won't work as it's the first step:

    ComPtr<IDXGIDevice3> dxgiDevice;
    DX::ThrowIfFailed(
        m_d3dDevice.As(&dxgiDevice)
        );

    ComPtr<IDXGIAdapter> dxgiAdapter;
    DX::ThrowIfFailed(
        dxgiDevice->GetAdapter(&dxgiAdapter)
        );

    ComPtr<IDXGIFactory4> dxgiFactory;
    DX::ThrowIfFailed(
        dxgiAdapter->GetParent(IID_PPV_ARGS(&dxgiFactory))
        );

For Direct3D 12, you should always create the DXGI factory explicitly. See Anatomy of Direct3D 12 Create Device.

In Direct3D 12 swap chains, you explicitly control the backbuffer swapping behavior. Ideally you'd use DXGI_SWAP_CHAIN_FLAG_FRAME_LATENCY_WAITABLE_OBJECT and then use the waitable object to throttle your rendering speed instead. You can set the latency count via IDXGISwapChain2::SetMaximumFrameLatency which defaults to 3 (MSDN is currently wrong about the defaults).

If you want to support 'higher-than-refresh-rate' updates (such as nVidia G-Sync or AMD FreeSync), then you use the new DXGI_PRESENT_ALLOW_TEARING flag for Present. For details on using this flag, see MSDN or this YouTube video.

See also DirectX 12: Presentation Modes In Windows 10 (YouTube).

Chuck Walbourn
  • 38,259
  • 2
  • 58
  • 81
  • Thanks for the reply Chuck. I already use an explicitly created factory, 'CreateDXGIFactory1(__uuidof(IDXGIFactory4), &dxgiFactory)' then scan DXGI adapters to find one that supports Direct3D 12, then create the device similar to the steps described in your blog. 'D3D12CreateDevice(myAdapter, D3D_FEATURE_LEVEL_11_0, __uuidof(ID3D12Device), &myDevice)' So unless i misunderstood your reply, I'm still not sure why i can't acquire IDXGIDevice1. My understanding of frame latency, is that is a value that is <= than the the swap chain's buffer count to limit the driver's present queue – K Klip Nov 04 '16 at 18:10
  • You can use ``IDXGISwapChain2::SetMaximumFrameLatency`` instead. – Chuck Walbourn Nov 07 '16 at 17:42
  • Note you can use ``IDXGISwapChain2::SetMaximumFrameLatency`` for waitable swapchains only. – Chuck Walbourn Nov 08 '16 at 20:46