2

I have been trying to make an application that utilizes the desktop duplication api, but having no experience with directx it is turning out to be quite a challenge. Everything seems to work until I call output1->DuplicateOutput()at which point it returns E_NOINTERFACE. This error is not defined in the msdn documentation so I am having trouble diagnosing the problem. I think that this code should work, but I must be missing something.

#include <windows.h>
#include <d3d12.h>
#include <dxgi1_5.h>

int main()
{
    HRESULT hr;
    ID3D12Debug *debug;
    hr = D3D12GetDebugInterface(IID_PPV_ARGS(&debug));
    debug->EnableDebugLayer();
    IDXGIFactory1 *factory;
    hr = CreateDXGIFactory1(IID_PPV_ARGS(&factory));
    IDXGIAdapter1 *adapter;
    hr = factory->EnumAdapters1(0, &adapter);
    factory->Release();
    IDXGIOutput *junkput;
    hr = adapter->EnumOutputs(0, &junkput);
    IDXGIOutput1 *output1;
    hr = junkput->QueryInterface(IID_PPV_ARGS(&output1));
    junkput->Release();
    ID3D12Device *device;
    hr = D3D12CreateDevice(adapter, D3D_FEATURE_LEVEL_11_0, IID_PPV_ARGS(&device));
    IDXGIOutputDuplication *dupl;
    hr = output1->DuplicateOutput(device, &dupl);
    return 0;
}

In my debug window I notice that I am getting two _com_errors when I call output1->DuplicateOutput.

Update:

I narrowed the problem down to the fact that I am using a ID3D12Device instead of an ID3D11Device. As exemplified by the fact that this code works:

ID3D11Device *device;
D3D_FEATURE_LEVEL reallevel;
ID3D11DeviceContext *context;
hr = D3D11CreateDevice(adapter, D3D_DRIVER_TYPE_UNKNOWN, nullptr, NULL, featurelevels, ARRAYSIZE(featurelevels), D3D11_SDK_VERSION, &device, &reallevel, &context);
IDXGIOutputDuplication *dupl;
hr = output1->DuplicateOutput(device, &dupl);

What I don't understand is why that is a problem. Isn't the desktop duplication api compatible with directx 12?

Alex
  • 316
  • 4
  • 12
  • If I understand rightly, DXGI is based on COM. At any rate, E_NOINTERFACE is a COM error. So presumably you have to call CoInitializeEx before using any of the interfaces. See also https://blogs.msdn.microsoft.com/oldnewthing/20041213-00/?p=37043 which might or might not be relevant. – Harry Johnston Oct 21 '16 at 00:00
  • It's not immediately obvious, why you release the adapter you are still using (indirectly). Anyway, [ID3D12Debug::EnableDebugLayer](https://msdn.microsoft.com/en-us/library/windows/desktop/dn986877.aspx). – IInspectable Oct 21 '16 at 00:03
  • I tried calling CoInitializeEx at the beginning of my program, but to no avail. – Alex Oct 21 '16 at 01:35
  • I also did `ID3D12Debug *debug; D3D12GetDebugInterface(IID_PPV_ARGS(&debug)); debug->EnableDebugLayer();` In my debug window this appears: `Microsoft C++ exception: _com_error at memory location 0x0099F6E0. Microsoft C++ exception: _com_error at memory location 0x0099FA10.` – Alex Oct 21 '16 at 01:44
  • To use the debug layer, you need to install the optional feature named graphic tools. Or the Get return `nullptr`, and your unprotected `Enable` call will crash. – galop1n Oct 21 '16 at 23:57
  • I must already have that installed because it is not returning null and enable is not crashing. – Alex Oct 22 '16 at 00:04
  • Note that the Direct3D runtime uses C++ exceptions internally to handle some error cases, but they are processed and don't get returned to the called application as exceptions, just ``HRESULT`` values. As such, it may well be "normal" to see ``_com_error`` coming from the runtime. What matter is the ``HRESULT``. – Chuck Walbourn Oct 24 '16 at 16:33

1 Answers1

4

DXGI DuplicateOutput does not support DirectX 12 devices yet. As you have no experience using DirectX, you should be using DirectX 11 anyhow. DirectX 12 is an API designed for graphics experts who are assumed to already be deeply familiar with DirectX 11.

Note that D3D11On12CreateDevice devices should work with DXGI DuplicateOutput, but I've not tried it myself.

Chuck Walbourn
  • 38,259
  • 2
  • 58
  • 81