I found he had the same problem as me ( https://stackoverflow.com/questions/40165786/calling-duplicateoutput-with-d3d12device-fails-with-e-nointerface ). I tryed 11on12, I call IDXGIOutputDuplication::AcquireNextFrame and return AcquireNextFrame error. Does D3D12 not support duplicateoutput?
D3D12 can use IDXGIOutputDuplication::AcquireNextFrame?
I want to use ID3D12Device to create to IDXGIOutput , but ID3D12Device cant queryinterface to get IDXGIDevice2. I found ID3D12Device can create ID3D11Device by d3d11on12.h , but it will return DXGI_ERROR_ACCESS_LOST error when call IDXGIOutputDuplication::AcquireNextFrame. I want to know if IDXGIOutputDuplication::AcquireNextFrame support d3d12.
Below is the initialization code:
ComPtr<ID3D12Device> pDevice12;
ComPtr<ID3D12CommandQueue> pDevice12CommandQueue;
ComPtr<ID3D11Device> pDevice11;
ComPtr<ID3D11DeviceContext> pDevice11Context;
ComPtr<ID3D11Texture2D> pDopTex2D;
std::shared_ptr<DDAImpl> pDDACapture = nullptr;
HRESULT hr = S_OK;
/// Driver types supported
D3D_DRIVER_TYPE DriverTypes[] =
{
D3D_DRIVER_TYPE_HARDWARE,
D3D_DRIVER_TYPE_WARP,
D3D_DRIVER_TYPE_REFERENCE,
};
UINT NumDriverTypes = ARRAYSIZE(DriverTypes);
/// Feature levels supported
D3D_FEATURE_LEVEL FeatureLevels[] =
{
D3D_FEATURE_LEVEL_11_0,
D3D_FEATURE_LEVEL_10_1,
D3D_FEATURE_LEVEL_10_0,
D3D_FEATURE_LEVEL_9_1
};
UINT NumFeatureLevels = ARRAYSIZE(FeatureLevels);
D3D_FEATURE_LEVEL FeatureLevel = D3D_FEATURE_LEVEL_11_0;
HRESULT res = D3D12CreateDevice(nullptr, FeatureLevel, IID_PPV_ARGS(pDevice12.GetAddressOf()));
CHECK_FAIL_AND_RETURN(res, D3D12CreateDevice)
D3D12_COMMAND_QUEUE_DESC queueDesc = { D3D12_COMMAND_LIST_TYPE_DIRECT };
//queueDesc.Flags = D3D12_COMMAND_QUEUE_FLAG_NONE;
//queueDesc.Type = D3D12_COMMAND_LIST_TYPE_DIRECT;
res = pDevice12->CreateCommandQueue(&queueDesc, IID_PPV_ARGS(pDevice12CommandQueue.GetAddressOf()));
CHECK_FAIL_AND_RETURN(res, CreateCommandQueue)
//ComPtr<IDXGIDevice2> pDevice2;
//res = pDevice12->QueryInterface(__uuidof(IDXGIDevice2), (void**)pDevice2.GetAddressOf());
//CHECK_FAIL_AND_RETURN(res, IDXGIDevice2)
res = D3D11On12CreateDevice(pDevice12.Get(),
D3D11_CREATE_DEVICE_BGRA_SUPPORT | D3D11_CREATE_DEVICE_VIDEO_SUPPORT,
FeatureLevels,
NumFeatureLevels,
reinterpret_cast<IUnknown**>(pDevice12CommandQueue.GetAddressOf()),
1,
0,
pDevice11.GetAddressOf(),
pDevice11Context.GetAddressOf(),
nullptr);
CHECK_FAIL_AND_RETURN(res, D3D11On12CreateDevice);
if (pDevice11) {
printf("Get Device success \n");
}
//HRESULT res;
//InitDXGI_ON_11(pDevice11.GetAddressOf(), pDevice11Context.GetAddressOf());
if (pDevice11 && pDevice11Context) {
pDDACapture = std::make_shared<DDAImpl>(pDevice11.Get(), pDevice11Context.Get());
res = pDDACapture->Init();
CHECK_FAIL_AND_RETURN(res, DDAImpl->init);
}
int frames = 10;
while (frames > 0) {
res = pDDACapture->GetCapturedFrame(pDopTex2D.GetAddressOf(), 17);
if (res == DXGI_ERROR_WAIT_TIMEOUT) {
continue;
}
else {
std::cout << "######################capture a frame success" << std::endl;
}
frames -= 1;
}
Windows development | Windows API - Win32
4 answers
Sort by: Most helpful
-
Xiaopo Yang - MSFT 12,736 Reputation points Microsoft External Staff
2022-01-19T08:14:02.567+00:00 I have written a sample to test. The result is that ID3D12Device object doesn't implement IDXGIDevice. But there is a workaround(GetAdapterLuid) to retrieve the IDXGIAdapter which is used to create D3D12 Device. And the IDXGIAdapter can be used to do something.
void GetHardwareAdapter(IDXGIFactory4* pFactory, IDXGIAdapter1** ppAdapter) { *ppAdapter = nullptr; for (UINT adapterIndex = 0; ; ++adapterIndex) { IDXGIAdapter1* pAdapter = nullptr; if (DXGI_ERROR_NOT_FOUND == pFactory->EnumAdapters1(adapterIndex, &pAdapter)) { // No more adapters to enumerate. break; } // Check to see if the adapter supports Direct3D 12, but don't create the // actual device yet. if (SUCCEEDED(D3D12CreateDevice(pAdapter, D3D_FEATURE_LEVEL_11_0, _uuidof(ID3D12Device), nullptr))) { *ppAdapter = pAdapter; return; } pAdapter->Release(); } } HRESULT CreateDirect3DDevice(IDXGIAdapter1* g) { CComPtr<IDXGIFactory4> factory; HRESULT r = (CreateDXGIFactory1(IID_PPV_ARGS(&factory))); if (SUCCEEDED(r)) { } CComPtr<ID3D12Device> lDevice; /*if (false) { CComPtr<IDXGIAdapter> warpAdapter; r = (factory->EnumWarpAdapter(IID_PPV_ARGS(&warpAdapter))); r = (D3D12CreateDevice( warpAdapter, D3D_FEATURE_LEVEL_11_0, IID_PPV_ARGS(&lDevice) )); } else*/ { CComPtr<IDXGIAdapter1> hardwareAdapter; GetHardwareAdapter(factory, &hardwareAdapter); r = (D3D12CreateDevice( hardwareAdapter, D3D_FEATURE_LEVEL_11_0, IID_PPV_ARGS(&lDevice) )); } CComPtr<IDXGIDevice> lDxgiDevice; r = lDevice->QueryInterface(IID_PPV_ARGS(&lDxgiDevice)); LUID uid = lDevice->GetAdapterLuid(); CComPtr<IDXGIAdapter> adapter; factory->EnumAdapterByLuid(uid, IID_PPV_ARGS(&adapter)); UINT Output = 0; CComPtr<IDXGIOutput> lDxgiOutput; r = adapter->EnumOutputs( Output, &lDxgiOutput); }
-
Mingkun Ma 1 Reputation point
2022-01-19T07:03:24.817+00:00 I cant QueryInterface using D3D12 Device
ComPtr<IDXGIFactory4> factory; HRESULT res = CreateDXGIFactory2(0, IID_PPV_ARGS(&factory)); CHECK_FAIL_AND_RETURN(res, CreateDXGIFactory2); ComPtr<IDXGIAdapter1> adpter; for (int index = 0; factory->EnumAdapters1(index, adpter.GetAddressOf()) != DXGI_ERROR_NOT_FOUND; ++index) { DXGI_ADAPTER_DESC1 desc; adpter->GetDesc1(&desc); printf("#####################\n"); if (desc.Flags & DXGI_ADAPTER_FLAG_SOFTWARE) { continue; } res = D3D12CreateDevice(adpter.Get(), D3D_FEATURE_LEVEL_11_1, __uuidof(ID3D12Device), nullptr); if (res == S_FALSE) { std::wstring str(desc.Description); if (-1 != str.find(L"NVIDIA", 0)) { wprintf_s(L"Output Describe: %s\n", desc.Description); break; } } } ComPtr<ID3D12Device> pD3D12Device; res = D3D12CreateDevice(adpter.Get(), D3D_FEATURE_LEVEL_11_1, __uuidof(ID3D12Device), reinterpret_cast<void**>(pD3D12Device.GetAddressOf())); CHECK_FAIL_AND_RETURN(res, D3D12CreateDevice ID3D12Device) ComPtr<IDXGIDevice> pIDXGDevice; res = pD3D12Device->QueryInterface(IID_PPV_ARGS(pIDXGDevice.GetAddressOf())); CHECK_FAIL_AND_RETURN(res, QueryInterface IDXGIDevice) -
Xiaopo Yang - MSFT 12,736 Reputation points Microsoft External Staff
2022-01-19T01:36:37.96+00:00 According to DXGI, DXGI is used by Direct3D 10, Direct3D 11 and Direct3D 12. There is a sample where D3D11 uses DXGI.