@@ -79,6 +79,29 @@ const std::vector<CaptureDevice>& CaptureManager::CaptureDevices()
7979 return m_captureDevices;
8080}
8181
82+ const std::vector<GraphicsAdapter>& CaptureManager::GraphicsAdapters ()
83+ {
84+ if (!m_graphicsAdapters.size ())
85+ {
86+ const auto & adapters = EnumerateAdapters ();
87+ int no = 1 ;
88+ for (auto adapter : adapters)
89+ {
90+ DXGI_ADAPTER_DESC desc;
91+ if (SUCCEEDED (adapter->GetDesc (&desc)))
92+ {
93+ if ((desc.VendorId == 0x1414 ) && (desc.DeviceId == 0x8c ))
94+ continue ; // Microsoft Basic Render Driver
95+
96+ wchar_t id[24 ];
97+ _snwprintf_s (id, 24 , L" %lx:%lx" , desc.AdapterLuid .HighPart , desc.AdapterLuid .LowPart );
98+ m_graphicsAdapters.emplace_back (no++, std::wstring (desc.Description ), std::wstring (id), adapter);
99+ }
100+ }
101+ }
102+ return m_graphicsAdapters;
103+ }
104+
82105bool CaptureManager::UpdateInput ()
83106{
84107 if (IsActive ())
@@ -97,30 +120,39 @@ DWORD WINAPI ThreadFuncProxy(LPVOID lpParam)
97120
98121bool CaptureManager::StartSession ()
99122{
100- if (!m_d3dDevice)
101- {
102- m_d3dDevice = CreateD3DDevice ();
103- m_d3dDevice->GetImmediateContext (m_context.put ());
104- }
105-
106- auto dxgiDevice = m_d3dDevice.as <IDXGIDevice>();
107- auto device = HasCaptureAPI () ? CreateDirect3DDevice (dxgiDevice.get ()) : nullptr ;
123+ bool hybrid = false ;
108124
109- // get GPU name
125+ if (!m_captureDevice)
110126 {
111- winrt::com_ptr<IDXGIAdapter> adapter ;
112- if (SUCCEEDED (dxgiDevice-> GetAdapter (adapter. put ())) )
127+ m_captureDevice = CreateD3DDevice (m_captureAdapter) ;
128+ if (m_captureAdapter != m_renderAdapter )
113129 {
114- DXGI_ADAPTER_DESC desc;
115- if (SUCCEEDED (adapter->GetDesc (&desc)))
130+ m_renderDevice = CreateD3DDevice (m_renderAdapter);
131+ hybrid = true ;
132+ }
133+ else
134+ {
135+ m_renderDevice = m_captureDevice;
136+ }
137+ m_renderDevice->GetImmediateContext (m_renderContext.put ());
138+
139+ // get actual GPU name
140+ {
141+ auto dxgiDevice = m_renderDevice.as <IDXGIDevice>();
142+ winrt::com_ptr<IDXGIAdapter> adapter;
143+ if (SUCCEEDED (dxgiDevice->GetAdapter (adapter.put ())))
116144 {
117- m_deviceName = std::wstring (desc.Description );
145+ DXGI_ADAPTER_DESC desc;
146+ if (SUCCEEDED (adapter->GetDesc (&desc)))
147+ {
148+ m_deviceName = std::wstring (desc.Description );
149+ }
118150 }
119151 }
120152 }
121153
122154#ifdef _DEBUG
123- m_d3dDevice ->QueryInterface (__uuidof (ID3D11Debug), reinterpret_cast <void **>(m_debug.put ()));
155+ m_renderDevice ->QueryInterface (__uuidof (ID3D11Debug), reinterpret_cast <void **>(m_debug.put ()));
124156#endif
125157
126158 winrt::Windows::Graphics::Capture::GraphicsCaptureItem captureItem {nullptr };
@@ -148,8 +180,8 @@ bool CaptureManager::StartSession()
148180 m_options.flipMode ,
149181 m_options.allowTearing ,
150182 m_options.useHDR ,
151- m_d3dDevice ,
152- m_context );
183+ m_renderDevice ,
184+ m_renderContext );
153185 UpdatePixelSize ();
154186 UpdateOutputSize ();
155187 UpdateOutputFlip ();
@@ -164,7 +196,7 @@ bool CaptureManager::StartSession()
164196 {
165197 winrt::com_ptr<ID3D11Texture2D> inputTexture;
166198 winrt::com_ptr<ID3D11ShaderResourceView> inputTextureView;
167- auto hr = DirectX::CreateWICTextureFromFileEx (m_d3dDevice .get (),
199+ auto hr = DirectX::CreateWICTextureFromFileEx (m_renderDevice .get (),
168200 m_options.imageFile .c_str (),
169201 0 ,
170202 D3D11_USAGE_DEFAULT,
@@ -182,7 +214,7 @@ bool CaptureManager::StartSession()
182214 m_options.imageWidth = desc.Width ;
183215 m_options.imageHeight = desc.Height ;
184216
185- m_session = make_unique<CaptureSession>(device, inputTexture, *m_shaderGlass, m_frameEvent);
217+ m_session = make_unique<CaptureSession>(inputTexture, *m_shaderGlass, m_frameEvent);
186218 UpdatePixelSize ();
187219 }
188220 else if (m_options.deviceFormatNo )
@@ -192,7 +224,7 @@ bool CaptureManager::StartSession()
192224 if (!FindDeviceFormat (m_options.deviceFormatNo , di, fi))
193225 return false ;
194226
195- m_deviceCapture.Start (m_d3dDevice , di->no , fi->no );
227+ m_deviceCapture.Start (m_renderDevice , di->no , fi->no );
196228
197229 // retrieve input image size
198230 auto inputTexture = m_deviceCapture.m_outputTexture ;
@@ -201,18 +233,19 @@ bool CaptureManager::StartSession()
201233 m_options.imageWidth = desc.Width ;
202234 m_options.imageHeight = desc.Height ;
203235
204- m_session = make_unique<CaptureSession>(device, inputTexture, *m_shaderGlass, m_frameEvent);
236+ m_session = make_unique<CaptureSession>(inputTexture, *m_shaderGlass, m_frameEvent);
205237 UpdatePixelSize ();
206238 }
207239 else
208240 {
209241 winrt::Windows::Graphics::DirectX::DirectXPixelFormat pixelFormat = m_options.useHDR ? winrt::Windows::Graphics::DirectX::DirectXPixelFormat::R16G16B16A16Float
210242 : winrt::Windows::Graphics::DirectX::DirectXPixelFormat::B8G8R8A8UIntNormalized;
211243
212- m_session = make_unique<CaptureSession>(device, captureItem, pixelFormat, *m_shaderGlass, m_options.maxCaptureRate , m_frameEvent);
244+ m_session =
245+ make_unique<CaptureSession>(m_captureDevice, hybrid ? m_renderDevice : nullptr , captureItem, pixelFormat, *m_shaderGlass, m_options.maxCaptureRate , m_frameEvent);
213246 }
214247
215- m_active = true ;
248+ m_active = true ;
216249 auto thread = CreateThread (NULL , 0 , ThreadFuncProxy, this , 0 , NULL );
217250 SetThreadPriority (thread, THREAD_PRIORITY_TIME_CRITICAL);
218251
@@ -239,7 +272,7 @@ void CaptureManager::UpdateCursor()
239272{
240273 if (m_options.captureCursor && m_options.transparent )
241274 {
242- m_cursorEmulator.Init (m_d3dDevice , m_instance, m_options.outputWindow );
275+ m_cursorEmulator.Init (m_renderDevice , m_instance, m_options.outputWindow );
243276 m_cursorEmulator.Start ();
244277 if (m_session)
245278 m_session->UpdateCursor (false );
@@ -451,7 +484,7 @@ void CaptureManager::SaveOutput(LPWSTR fileName)
451484{
452485 if (m_outputTexture)
453486 {
454- DirectX::SaveWICTextureToFile (m_context .get (), m_outputTexture.get (), GUID_ContainerFormatPng, fileName, nullptr , nullptr , true );
487+ DirectX::SaveWICTextureToFile (m_renderContext .get (), m_outputTexture.get (), GUID_ContainerFormatPng, fileName, nullptr , nullptr , true );
455488 }
456489}
457490
@@ -539,3 +572,20 @@ bool CaptureManager::FindDeviceFormat(int deviceFormatNo, std::vector<CaptureDev
539572
540573 return false ;
541574}
575+
576+ void CaptureManager::SetCaptureAdapters (const std::wstring& captureId, const std::wstring& renderId)
577+ {
578+ m_captureAdapter = nullptr ;
579+ m_renderAdapter = nullptr ;
580+ if (captureId.size () || renderId.size ())
581+ {
582+ const auto & graphicsAdapters = GraphicsAdapters ();
583+ for (const auto & ga : graphicsAdapters)
584+ {
585+ if (ga.id == captureId)
586+ m_captureAdapter = ga.adapter ;
587+ if (ga.id == renderId)
588+ m_renderAdapter = ga.adapter ;
589+ }
590+ }
591+ }
0 commit comments