1use crate::util::Share;
2use std::{
3 ffi::c_void,
4 sync::{
5 atomic::{AtomicU32, Ordering},
6 OnceLock,
7 },
8};
9use windows::{
10 core::{Interface, InterfaceRef},
11 Win32::Graphics::{Direct3D11::ID3D11Device, Dxgi::IDXGISwapChain},
12};
13
14static D3D_VERSION: AtomicU32 = AtomicU32::new(0);
16
17#[inline]
21pub fn d3d_version() -> u32 {
22 D3D_VERSION.load(Ordering::Relaxed)
23}
24
25static DXGI_SWAP_CHAIN: OnceLock<Share<InterfaceRef<'static, IDXGISwapChain>>> = OnceLock::new();
27
28#[inline]
30pub fn dxgi_swap_chain() -> Option<IDXGISwapChain> {
31 DXGI_SWAP_CHAIN
32 .get()
33 .map(|swap_chain| (*unsafe { swap_chain.get() }).to_owned())
34}
35
36#[inline]
38pub fn d3d11_device() -> Option<ID3D11Device> {
39 let swap_chain = dxgi_swap_chain()?;
40 unsafe { swap_chain.GetDevice() }.ok()
41}
42
43pub unsafe fn init_dxgi(id3d: *mut c_void, d3d_version: u32) {
45 D3D_VERSION.store(d3d_version, Ordering::Relaxed);
46 if d3d_version == 11 && !id3d.is_null() {
47 let swap_chain =
48 unsafe { IDXGISwapChain::from_raw_borrowed(&id3d) }.expect("invalid swap chain");
49 DXGI_SWAP_CHAIN.get_or_init(|| Share::new(InterfaceRef::from_interface(swap_chain)));
50 }
51}