1use core::ptr;
2
3use anyhow::Context;
4use asdf_overlay_event::GpuLuid;
5use parking_lot::Mutex;
6use windows::{
7 Win32::{
8 Foundation::HMODULE,
9 Graphics::{
10 Direct3D::{D3D_DRIVER_TYPE_HARDWARE, D3D_DRIVER_TYPE_UNKNOWN},
11 Direct3D11::{
12 D3D11_CREATE_DEVICE_BGRA_SUPPORT, D3D11_SDK_VERSION, D3D11CreateDevice,
13 ID3D11Device, ID3D11DeviceContext,
14 },
15 Dxgi::{IDXGIAdapter, IDXGIDevice},
16 },
17 },
18 core::Interface,
19};
20
21#[non_exhaustive]
23pub struct DxInterop {
24 pub gpu_id: GpuLuid,
28
29 pub device: ID3D11Device,
31
32 pub cx: Mutex<ID3D11DeviceContext>,
34}
35
36impl DxInterop {
37 pub fn new(adapter: Option<&IDXGIAdapter>) -> anyhow::Result<Self> {
41 unsafe {
42 let mut device = None;
43 let mut cx = None;
44 D3D11CreateDevice(
45 adapter,
46 if adapter.is_some() {
47 D3D_DRIVER_TYPE_UNKNOWN
48 } else {
49 D3D_DRIVER_TYPE_HARDWARE
50 },
51 HMODULE(ptr::null_mut()),
52 D3D11_CREATE_DEVICE_BGRA_SUPPORT,
53 None,
54 D3D11_SDK_VERSION,
55 Some(&mut device),
56 None,
57 Some(&mut cx),
58 )
59 .context("failed to create D3D11 interop device")?;
60 let device = device.unwrap();
61 let cx = cx.unwrap();
62
63 let luid = device
64 .cast::<IDXGIDevice>()?
65 .GetAdapter()?
66 .GetDesc()?
67 .AdapterLuid;
68 Ok(Self {
69 gpu_id: GpuLuid {
70 low: luid.LowPart,
71 high: luid.HighPart,
72 },
73 device,
74 cx: Mutex::new(cx),
75 })
76 }
77 }
78}