d3d_device.cc (3450B)
1 /* 2 * Copyright (c) 2016 The WebRTC project authors. All Rights Reserved. 3 * 4 * Use of this source code is governed by a BSD-style license 5 * that can be found in the LICENSE file in the root of the source 6 * tree. An additional intellectual property rights grant can be found 7 * in the file PATENTS. All contributing project authors may 8 * be found in the AUTHORS file in the root of the source tree. 9 */ 10 11 #include "modules/desktop_capture/win/d3d_device.h" 12 13 #include <utility> 14 #include <vector> 15 16 #include "modules/desktop_capture/win/desktop_capture_utils.h" 17 #include "rtc_base/logging.h" 18 19 namespace webrtc { 20 21 using Microsoft::WRL::ComPtr; 22 23 D3dDevice::D3dDevice() = default; 24 D3dDevice::D3dDevice(const D3dDevice& other) = default; 25 D3dDevice::D3dDevice(D3dDevice&& other) = default; 26 D3dDevice::~D3dDevice() = default; 27 28 bool D3dDevice::Initialize(const ComPtr<IDXGIAdapter>& adapter) { 29 dxgi_adapter_ = adapter; 30 if (!dxgi_adapter_) { 31 RTC_LOG(LS_WARNING) << "An empty IDXGIAdapter instance has been received."; 32 return false; 33 } 34 35 D3D_FEATURE_LEVEL feature_level; 36 // Default feature levels contain D3D 9.1 through D3D 11.0. 37 _com_error error = D3D11CreateDevice( 38 adapter.Get(), D3D_DRIVER_TYPE_UNKNOWN, nullptr, 39 D3D11_CREATE_DEVICE_BGRA_SUPPORT | D3D11_CREATE_DEVICE_SINGLETHREADED, 40 nullptr, 0, D3D11_SDK_VERSION, d3d_device_.GetAddressOf(), &feature_level, 41 context_.GetAddressOf()); 42 if (error.Error() != S_OK || !d3d_device_ || !context_) { 43 RTC_LOG(LS_WARNING) << "D3D11CreateDevice returned: " 44 << desktop_capture::utils::ComErrorToString(error); 45 return false; 46 } 47 48 if (feature_level < D3D_FEATURE_LEVEL_11_0) { 49 RTC_LOG(LS_WARNING) 50 << "D3D11CreateDevice returned an instance without DirectX 11 support, " 51 << "level " << feature_level << ". Following initialization may fail."; 52 // D3D_FEATURE_LEVEL_11_0 is not officially documented on MSDN to be a 53 // requirement of Dxgi duplicator APIs. 54 } 55 56 error = d3d_device_.As(&dxgi_device_); 57 if (error.Error() != S_OK || !dxgi_device_) { 58 RTC_LOG(LS_WARNING) 59 << "ID3D11Device is not an implementation of IDXGIDevice, " 60 << "this usually means the system does not support DirectX " 61 << "11. Error received: " 62 << desktop_capture::utils::ComErrorToString(error); 63 return false; 64 } 65 66 return true; 67 } 68 69 // static 70 std::vector<D3dDevice> D3dDevice::EnumDevices() { 71 ComPtr<IDXGIFactory1> factory; 72 _com_error error = 73 CreateDXGIFactory1(__uuidof(IDXGIFactory1), 74 reinterpret_cast<void**>(factory.GetAddressOf())); 75 if (error.Error() != S_OK || !factory) { 76 RTC_LOG(LS_WARNING) << "Cannot create IDXGIFactory1: " 77 << desktop_capture::utils::ComErrorToString(error); 78 return std::vector<D3dDevice>(); 79 } 80 81 std::vector<D3dDevice> result; 82 for (int i = 0;; i++) { 83 ComPtr<IDXGIAdapter> adapter; 84 error = factory->EnumAdapters(i, adapter.GetAddressOf()); 85 if (error.Error() == S_OK) { 86 D3dDevice device; 87 if (device.Initialize(adapter)) { 88 result.push_back(std::move(device)); 89 } 90 } else if (error.Error() == DXGI_ERROR_NOT_FOUND) { 91 break; 92 } else { 93 RTC_LOG(LS_WARNING) 94 << "IDXGIFactory1::EnumAdapters returned an unexpected error: " 95 << desktop_capture::utils::ComErrorToString(error); 96 } 97 } 98 return result; 99 } 100 101 } // namespace webrtc