Вызов DuplicateOutput с помощью D3D12Device завершается с ошибкой E_NOINTERFACE

#c #c #windows #directx #directx-12

#c #c #Windows #directx #directx-12 #c

Вопрос:

Я пытался создать приложение, которое использует API дублирования рабочего стола, но, не имея опыта работы с directx, это оказывается довольно сложной задачей. Кажется, все работает, пока я не вызову output1->DuplicateOutput() , после чего он возвращает E_NOINTERFACE. Эта ошибка не определена в документации msdn, поэтому у меня возникли проблемы с диагностикой проблемы. Я думаю, что этот код должен работать, но я, должно быть, чего-то не хватает.

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

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

В моем окне отладки я замечаю, что при вызове я получаю два _com_errors output1->DuplicateOutput .

Обновить:

Я сузил проблему до того факта, что я использую ID3D12Device вместо ID3D11Device. Примером может служить тот факт, что этот код работает:

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

Чего я не понимаю, так это почему это проблема. Разве api дублирования рабочего стола не совместим с directx 12?

Комментарии:

1. Если я правильно понимаю, DXGI основан на COM. В любом случае, E_NOINTERFACE — это ошибка COM. Поэтому, предположительно, вам нужно вызвать CoInitializeEx перед использованием любого из интерфейсов. Смотрите также blogs.msdn.microsoft.com/oldnewthing/20041213-00/?p=37043 что может иметь значение, а может и не иметь.

2. Не сразу понятно, почему вы выпускаете адаптер, который вы все еще используете (косвенно). В любом случае, ID3D12Debug::EnableDebugLayer .

3. Я пытался вызвать CoInitializeEx в начале моей программы, но безрезультатно.

4. Я также сделал ID3D12Debug *debug; D3D12GetDebugInterface(IID_PPV_ARGS(amp;debug)); debug->EnableDebugLayer(); В моем окне отладки появляется это: Microsoft C exception: _com_error at memory location 0x0099F6E0. Microsoft C exception: _com_error at memory location 0x0099FA10.

5. Чтобы использовать уровень отладки, вам необходимо установить дополнительную функцию с именем graphic tools. Или возврат Get nullptr , и ваш незащищенный Enable вызов завершится сбоем.

Ответ №1:

DXGI DuplicateOutput пока не поддерживает устройства DirectX 12. Поскольку у вас нет опыта использования DirectX, вы все равно должны использовать DirectX 11. DirectX 12 — это API, предназначенный для графических экспертов, которые, как предполагается, уже хорошо знакомы с DirectX 11.

Обратите внимание, что D3D11On12CreateDevice устройства должны работать с DXGI DuplicateOutput , но я сам этого не пробовал.

Комментарии:

1. Я не думаю, что DuplicateOutput работает с 11On12. Все еще терпит неудачу там, где D3D11 работает нормально.