diff --git a/wgpu-hal/Cargo.toml b/wgpu-hal/Cargo.toml
index 3a64b8e44bc..82b3c3fb5be 100644
--- a/wgpu-hal/Cargo.toml
+++ b/wgpu-hal/Cargo.toml
@@ -103,6 +103,14 @@ vulkan = [
"dep:smallvec",
"dep:windows",
"windows/Win32",
+ "windows/Win32_System",
+ "windows/Win32_System_Diagnostics",
+ "windows/Win32_System_Diagnostics_Debug",
+ "windows/Win32_System_Kernel",
+ "windows/Win32_Graphics_Dxgi_Common",
+ "windows/Win32_Graphics_Direct3D",
+ "windows/Win32_Graphics_Direct3D12",
+ "windows/Win32_System_Performance",
]
gles = [
"naga/glsl-out",
diff --git a/wgpu-hal/src/auxil/dxgi/factory.rs b/wgpu-hal/src/auxil/dxgi/factory.rs
index ac050bcd332..529c45f6843 100644
--- a/wgpu-hal/src/auxil/dxgi/factory.rs
+++ b/wgpu-hal/src/auxil/dxgi/factory.rs
@@ -1,9 +1,12 @@
use alloc::{string::String, vec::Vec};
use core::ops::Deref;
-use windows::{core::Interface as _, Win32::Graphics::Dxgi};
+use windows::{
+ core::Interface as _,
+ Win32::{Foundation, Graphics::Dxgi},
+};
-use crate::dx12::DxgiLib;
+use crate::auxil::dxgi::library::DxgiLib;
use super::result::HResult as _;
@@ -139,6 +142,27 @@ impl DxgiFactory {
Self::Factory6(f) => Some(f),
}
}
+
+ /// Returns `true` if the factory supports the ALLOW_TEARING present feature.
+ pub fn supports_allow_tearing(&self) -> bool {
+ let mut supports_allow_tearing = false;
+ if let Some(factory5) = self.as_factory5() {
+ let mut allow_tearing = Foundation::FALSE;
+ let hr = unsafe {
+ factory5.CheckFeatureSupport(
+ Dxgi::DXGI_FEATURE_PRESENT_ALLOW_TEARING,
+ <*mut _>::cast(&mut allow_tearing),
+ size_of_val(&allow_tearing) as u32,
+ )
+ };
+
+ match hr {
+ Err(err) => log::warn!("Unable to check for tearing support: {err}"),
+ Ok(()) => supports_allow_tearing = true,
+ }
+ }
+ supports_allow_tearing
+ }
}
pub fn create_factory(
diff --git a/wgpu-hal/src/auxil/dxgi/library.rs b/wgpu-hal/src/auxil/dxgi/library.rs
new file mode 100644
index 00000000000..6a5c5b2c888
--- /dev/null
+++ b/wgpu-hal/src/auxil/dxgi/library.rs
@@ -0,0 +1,263 @@
+use core::ops::Deref;
+use std::ffi;
+use windows::core::Interface as _;
+use windows::Win32::Graphics::{Direct3D, Direct3D12, Dxgi};
+
+use crate::auxil::dxgi::{factory::DxgiAdapter, result::HResult as _};
+
+#[derive(Debug)]
+pub(crate) struct DynLib {
+ inner: libloading::Library,
+}
+
+impl DynLib {
+ pub unsafe fn new
(filename: P) -> Result
+ where
+ P: AsRef,
+ {
+ unsafe { libloading::Library::new(filename) }.map(|inner| Self { inner })
+ }
+
+ pub unsafe fn get(
+ &self,
+ symbol: &[u8],
+ ) -> Result, crate::DeviceError> {
+ unsafe { self.inner.get(symbol) }.map_err(|e| match e {
+ libloading::Error::GetProcAddress { .. } | libloading::Error::GetProcAddressUnknown => {
+ crate::DeviceError::Unexpected
+ }
+ libloading::Error::IncompatibleSize
+ | libloading::Error::CreateCString { .. }
+ | libloading::Error::CreateCStringWithTrailing { .. } => crate::hal_internal_error(e),
+ _ => crate::DeviceError::Unexpected, // could be unreachable!() but we prefer to be more robust
+ })
+ }
+}
+
+#[derive(Debug)]
+pub(crate) struct D3D12Lib {
+ lib: DynLib,
+}
+
+impl D3D12Lib {
+ pub fn new() -> Result {
+ unsafe { DynLib::new("d3d12.dll").map(|lib| Self { lib }) }
+ }
+
+ pub fn create_device(
+ &self,
+ adapter: &DxgiAdapter,
+ feature_level: Direct3D::D3D_FEATURE_LEVEL,
+ ) -> Result