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