From e6d7e5fea7c828c93c550134834572196de7b3de Mon Sep 17 00:00:00 2001 From: Night_Hunter Date: Sun, 13 Apr 2025 15:57:55 +1200 Subject: [PATCH 01/23] add dx12 dcomp option to backend options --- deno_webgpu/lib.rs | 1 + tests/src/init.rs | 1 + wgpu-hal/examples/ray-traced-triangle/main.rs | 1 + wgpu-types/src/instance.rs | 8 +++++++- 4 files changed, 10 insertions(+), 1 deletion(-) diff --git a/deno_webgpu/lib.rs b/deno_webgpu/lib.rs index 44ed02ff060..e144103552d 100644 --- a/deno_webgpu/lib.rs +++ b/deno_webgpu/lib.rs @@ -151,6 +151,7 @@ impl GPU { backend_options: wgpu_types::BackendOptions { dx12: wgpu_types::Dx12BackendOptions { shader_compiler: wgpu_types::Dx12Compiler::Fxc, + use_dcomp: false, }, gl: wgpu_types::GlBackendOptions::default(), noop: wgpu_types::NoopBackendOptions::default(), diff --git a/tests/src/init.rs b/tests/src/init.rs index 6f93508c206..3fe37b515cf 100644 --- a/tests/src/init.rs +++ b/tests/src/init.rs @@ -46,6 +46,7 @@ pub fn initialize_instance(backends: wgpu::Backends, params: &TestParameters) -> backend_options: wgpu::BackendOptions { dx12: wgpu::Dx12BackendOptions { shader_compiler: dx12_shader_compiler, + use_dcomp: false, }, gl: wgpu::GlBackendOptions { fence_behavior: if cfg!(target_family = "wasm") { diff --git a/wgpu-hal/examples/ray-traced-triangle/main.rs b/wgpu-hal/examples/ray-traced-triangle/main.rs index 9e2a7771e12..8ca470545b5 100644 --- a/wgpu-hal/examples/ray-traced-triangle/main.rs +++ b/wgpu-hal/examples/ray-traced-triangle/main.rs @@ -241,6 +241,7 @@ impl Example { backend_options: wgpu_types::BackendOptions { dx12: Dx12BackendOptions { shader_compiler: wgpu_types::Dx12Compiler::default_dynamic_dxc(), + use_dcomp: false, }, ..Default::default() }, diff --git a/wgpu-types/src/instance.rs b/wgpu-types/src/instance.rs index ff0c378a5eb..159c7294381 100644 --- a/wgpu-types/src/instance.rs +++ b/wgpu-types/src/instance.rs @@ -289,6 +289,8 @@ impl GlBackendOptions { pub struct Dx12BackendOptions { /// Which DX12 shader compiler to use. pub shader_compiler: Dx12Compiler, + /// Whether to use DirectComposition for managing presentation. + pub use_dcomp: bool, } impl Dx12BackendOptions { @@ -300,6 +302,7 @@ impl Dx12BackendOptions { let compiler = Dx12Compiler::from_env().unwrap_or_default(); Self { shader_compiler: compiler, + use_dcomp: false, } } @@ -309,7 +312,10 @@ impl Dx12BackendOptions { #[must_use] pub fn with_env(self) -> Self { let shader_compiler = self.shader_compiler.with_env(); - Self { shader_compiler } + Self { + shader_compiler, + use_dcomp: false, + } } } From c328699ba3fcb14fa8c11f50f7b30c22775e5cbb Mon Sep 17 00:00:00 2001 From: Night_Hunter Date: Sun, 13 Apr 2025 16:26:34 +1200 Subject: [PATCH 02/23] impl dcomp for the dx12 backend --- wgpu-hal/Cargo.toml | 2 + wgpu-hal/src/dx12/adapter.rs | 6 +- wgpu-hal/src/dx12/instance.rs | 26 +++++-- wgpu-hal/src/dx12/mod.rs | 142 +++++++++++++++++++++++++++++++++- 4 files changed, 166 insertions(+), 10 deletions(-) diff --git a/wgpu-hal/Cargo.toml b/wgpu-hal/Cargo.toml index 9d76061d497..017e4dbc9d3 100644 --- a/wgpu-hal/Cargo.toml +++ b/wgpu-hal/Cargo.toml @@ -141,6 +141,8 @@ dx12 = [ "windows/Win32_Graphics_Direct3D_Dxc", "windows/Win32_Graphics_Direct3D", "windows/Win32_Graphics_Direct3D12", + "windows/Win32_Graphics_Direct3D11", + "windows/Win32_Graphics_Direct3D11on12", "windows/Win32_Graphics_DirectComposition", "windows/Win32_Graphics_Dxgi_Common", "windows/Win32_Security", diff --git a/wgpu-hal/src/dx12/adapter.rs b/wgpu-hal/src/dx12/adapter.rs index 50aa80ad28c..603610a79a6 100644 --- a/wgpu-hal/src/dx12/adapter.rs +++ b/wgpu-hal/src/dx12/adapter.rs @@ -846,7 +846,10 @@ impl crate::Adapter for super::Adapter { ) -> Option { let current_extent = { match surface.target { - SurfaceTarget::WndHandle(wnd_handle) => { + SurfaceTarget::WndHandle(wnd_handle) + | SurfaceTarget::VisualFromWndHandle { + handle: wnd_handle, .. + } => { let mut rect = Default::default(); if unsafe { WindowsAndMessaging::GetClientRect(wnd_handle, &mut rect) }.is_ok() { @@ -890,6 +893,7 @@ impl crate::Adapter for super::Adapter { composite_alpha_modes: match surface.target { SurfaceTarget::WndHandle(_) => vec![wgt::CompositeAlphaMode::Opaque], SurfaceTarget::Visual(_) + | SurfaceTarget::VisualFromWndHandle { .. } | SurfaceTarget::SurfaceHandle(_) | SurfaceTarget::SwapChainPanel(_) => vec![ wgt::CompositeAlphaMode::Auto, diff --git a/wgpu-hal/src/dx12/instance.rs b/wgpu-hal/src/dx12/instance.rs index ef02c8aca7b..61b591be9e4 100644 --- a/wgpu-hal/src/dx12/instance.rs +++ b/wgpu-hal/src/dx12/instance.rs @@ -108,6 +108,7 @@ impl crate::Instance for super::Instance { factory, factory_media, library: Arc::new(lib_main), + use_dcomp: desc.backend_options.dx12.use_dcomp, _lib_dxgi: lib_dxgi, supports_allow_tearing, flags: desc.flags, @@ -121,14 +122,25 @@ impl crate::Instance for super::Instance { window_handle: raw_window_handle::RawWindowHandle, ) -> Result { match window_handle { - raw_window_handle::RawWindowHandle::Win32(handle) => Ok(super::Surface { - factory: self.factory.clone(), - factory_media: self.factory_media.clone(), + raw_window_handle::RawWindowHandle::Win32(handle) => { // https://github.com/rust-windowing/raw-window-handle/issues/171 - target: SurfaceTarget::WndHandle(Foundation::HWND(handle.hwnd.get() as *mut _)), - supports_allow_tearing: self.supports_allow_tearing, - swap_chain: RwLock::new(None), - }), + let handle = Foundation::HWND(handle.hwnd.get() as *mut _); + let target = if self.use_dcomp { + SurfaceTarget::VisualFromWndHandle { + handle, + dcomp_state: Default::default(), + } + } else { + SurfaceTarget::WndHandle(handle) + }; + Ok(super::Surface { + factory: self.factory.clone(), + factory_media: self.factory_media.clone(), + target, + supports_allow_tearing: self.supports_allow_tearing, + swap_chain: RwLock::new(None), + }) + } _ => Err(crate::InstanceError::new(format!( "window handle {window_handle:?} is not a Win32 handle" ))), diff --git a/wgpu-hal/src/dx12/mod.rs b/wgpu-hal/src/dx12/mod.rs index 09c4f884202..41ebc549f59 100644 --- a/wgpu-hal/src/dx12/mod.rs +++ b/wgpu-hal/src/dx12/mod.rs @@ -95,7 +95,7 @@ use windows::{ core::{Free, Interface}, Win32::{ Foundation, - Graphics::{Direct3D, Direct3D12, DirectComposition, Dxgi}, + Graphics::{Direct3D, Direct3D11, Direct3D11on12, Direct3D12, DirectComposition, Dxgi}, System::Threading, }, }; @@ -458,6 +458,7 @@ pub struct Instance { factory_media: Option, library: Arc, supports_allow_tearing: bool, + use_dcomp: bool, _lib_dxgi: DxgiLib, flags: wgt::InstanceFlags, dxc_container: Option>, @@ -527,9 +528,21 @@ struct SwapChain { size: wgt::Extent3d, } +struct DCompState { + visual: DirectComposition::IDCompositionVisual, + device: DirectComposition::IDCompositionDevice, + // Must be kept alive but is otherwise unused after initialization. + _target: DirectComposition::IDCompositionTarget, +} + enum SurfaceTarget { /// Borrowed, lifetime externally managed WndHandle(Foundation::HWND), + /// `handle` is borrowed, lifetime externally managed + VisualFromWndHandle { + handle: Foundation::HWND, + dcomp_state: RwLock>, + }, Visual(DirectComposition::IDCompositionVisual), /// Borrowed, lifetime externally managed SurfaceHandle(Foundation::HANDLE), @@ -1228,7 +1241,9 @@ impl crate::Surface for Surface { Flags: flags.0 as u32, }; let swap_chain1 = match self.target { - SurfaceTarget::Visual(_) | SurfaceTarget::SwapChainPanel(_) => { + SurfaceTarget::Visual(_) + | SurfaceTarget::VisualFromWndHandle { .. } + | SurfaceTarget::SwapChainPanel(_) => { profiling::scope!("IDXGIFactory2::CreateSwapChainForComposition"); unsafe { self.factory.CreateSwapChainForComposition( @@ -1275,6 +1290,128 @@ impl crate::Surface for Surface { match &self.target { SurfaceTarget::WndHandle(_) | SurfaceTarget::SurfaceHandle(_) => {} + SurfaceTarget::VisualFromWndHandle { + handle, + dcomp_state, + } => { + let mut dcomp_state = dcomp_state.write(); + let dcomp_state = match dcomp_state.as_mut() { + Some(s) => s, + None => { + let mut d3d11_device = None; + { + profiling::scope!("Direct3D11on12::D3D11On12CreateDevice"); + unsafe { + Direct3D11on12::D3D11On12CreateDevice( + &device.raw, + Direct3D11::D3D11_CREATE_DEVICE_BGRA_SUPPORT.0, + None, + None, + 0, + Some(&mut d3d11_device), + None, + None, + ) + } + .map_err(|err| { + log::error!( + "Direct3D11on12::D3D11On12CreateDevice failed: {err}" + ); + crate::SurfaceError::Other( + "Direct3D11on12::D3D11On12CreateDevice", + ) + })?; + } + let d3d11_device = d3d11_device.unwrap(); + + let dxgi_device = { + profiling::scope!("IDXGIDevice::QueryInterface"); + d3d11_device.cast::().map_err(|err| { + log::error!("IDXGIDevice::QueryInterface failed: {err}"); + crate::SurfaceError::Other("IDXGIDevice::QueryInterface") + })? + }; + + let dcomp_device = { + profiling::scope!( + "DirectComposition::DCompositionCreateDevice" + ); + unsafe { + DirectComposition::DCompositionCreateDevice::< + _, + DirectComposition::IDCompositionDevice, + >(&dxgi_device) + }.map_err(|err| { + log::error!( + "DirectComposition::DCompositionCreateDevice failed: {err}" + ); + crate::SurfaceError::Other( + "DirectComposition::DCompositionCreateDevice", + ) + })? + }; + + let target = { + profiling::scope!("IDCompositionDevice::CreateTargetForHwnd"); + unsafe { dcomp_device.CreateTargetForHwnd(*handle, false)} + .map_err(|err| { + log::error!( + "IDCompositionDevice::CreateTargetForHwnd failed: {err}" + ); + crate::SurfaceError::Other( + "IDCompositionDevice::CreateTargetForHwnd", + ) + })? + }; + + let visual = { + profiling::scope!("IDCompositionDevice::CreateVisual"); + unsafe { dcomp_device.CreateVisual() }.map_err(|err| { + log::error!( + "IDCompositionDevice::CreateVisual failed: {err}" + ); + crate::SurfaceError::Other( + "IDCompositionDevice::CreateVisual", + ) + })? + }; + + { + profiling::scope!("IDCompositionTarget::SetRoot"); + unsafe { target.SetRoot(&visual) }.map_err(|err| { + log::error!("IDCompositionTarget::SetRoot failed: {err}"); + crate::SurfaceError::Other("IDCompositionTarget::SetRoot") + })?; + } + + dcomp_state.insert(DCompState { + visual, + device: dcomp_device, + _target: target, + }) + } + }; + // Set the new swap chain as the content for the backing visual + // and commit the changes to the composition visual tree. + { + profiling::scope!("IDCompositionVisual::SetContent"); + unsafe { dcomp_state.visual.SetContent(&swap_chain1) }.map_err( + |err| { + log::error!("IDCompositionVisual::SetContent failed: {err}"); + crate::SurfaceError::Other("IDCompositionVisual::SetContent") + }, + )?; + } + + // Commit the changes to the composition device. + { + profiling::scope!("IDCompositionDevice::Commit"); + unsafe { dcomp_state.device.Commit() }.map_err(|err| { + log::error!("IDCompositionDevice::Commit failed: {err}"); + crate::SurfaceError::Other("IDCompositionDevice::Commit") + })?; + } + } SurfaceTarget::Visual(visual) => { if let Err(err) = unsafe { visual.SetContent(&swap_chain1) } { log::error!("Unable to SetContent: {err}"); @@ -1312,6 +1449,7 @@ impl crate::Surface for Surface { .into_device_result("MakeWindowAssociation")?; } SurfaceTarget::Visual(_) + | SurfaceTarget::VisualFromWndHandle { .. } | SurfaceTarget::SurfaceHandle(_) | SurfaceTarget::SwapChainPanel(_) => {} } From 1f70a9ab7deb45b13eefef5a418ece575a90711c Mon Sep 17 00:00:00 2001 From: Night_Hunter Date: Wed, 16 Apr 2025 18:22:28 +1200 Subject: [PATCH 03/23] Add Dcomp support to DX12 backend in changelog --- CHANGELOG.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 90d0f162172..5ba9a8477ae 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -42,6 +42,14 @@ Bottom level categories: ### New Features +#### DX12 + +- Add Dcomp support to DX12 backend. By @n1ght-hunter in [#7550](https://github.com/gfx-rs/wgpu/pull/7550). +```diff +-pub struct Dx12BackendOptions { pub shader_compiler: Dx12Compiler } ++pub struct Dx12BackendOptions { pub shader_compiler: Dx12Compiler, pub use_dcomp: bool } +``` + #### Naga ### Bux Fixes From 60a747c98639f169f03827f6b0d234095a43b1e4 Mon Sep 17 00:00:00 2001 From: Night_Hunter Date: Wed, 23 Apr 2025 16:28:04 +1200 Subject: [PATCH 04/23] move decomp to another module --- wgpu-hal/src/dx12/dcomp.rs | 110 +++++++++++++++++++++++++++++++++++++ wgpu-hal/src/dx12/mod.rs | 109 ++---------------------------------- 2 files changed, 114 insertions(+), 105 deletions(-) create mode 100644 wgpu-hal/src/dx12/dcomp.rs diff --git a/wgpu-hal/src/dx12/dcomp.rs b/wgpu-hal/src/dx12/dcomp.rs new file mode 100644 index 00000000000..6d66e1d9c3e --- /dev/null +++ b/wgpu-hal/src/dx12/dcomp.rs @@ -0,0 +1,110 @@ +use windows::Win32::{ + Foundation::HWND, + Graphics::{Direct3D11, Direct3D11on12, DirectComposition, Dxgi}, +}; +use windows_core::Interface as _; + +#[derive(Default)] +pub struct DCompState { + inner: Option, +} + +impl DCompState { + pub fn get_or_init( + &mut self, + hwnd: &HWND, + device: &super::Device, + ) -> Result<&mut InnerState, crate::SurfaceError> { + if self.inner.is_none() { + self.inner = Some(unsafe { InnerState::init(hwnd, device) }?); + } + Ok(self.inner.as_mut().unwrap()) + } +} + +pub struct InnerState { + pub visual: DirectComposition::IDCompositionVisual, + pub device: DirectComposition::IDCompositionDevice, + // Must be kept alive but is otherwise unused after initialization. + pub _target: DirectComposition::IDCompositionTarget, +} + +impl InnerState { + /// Creates a DirectComposition device and a target for the given window handle. + /// From a Direct3D 12 device, it creates a Direct3D 11 device and then a DirectComposition device. + pub unsafe fn init(hwnd: &HWND, device: &super::Device) -> Result { + let mut d3d11_device = None; + { + profiling::scope!("Direct3D11on12::D3D11On12CreateDevice"); + unsafe { + Direct3D11on12::D3D11On12CreateDevice( + &device.raw, + Direct3D11::D3D11_CREATE_DEVICE_BGRA_SUPPORT.0, + None, + None, + 0, + Some(&mut d3d11_device), + None, + None, + ) + } + .map_err(|err| { + log::error!("Direct3D11on12::D3D11On12CreateDevice failed: {err}"); + crate::SurfaceError::Other("Direct3D11on12::D3D11On12CreateDevice") + })?; + } + let d3d11_device = d3d11_device.unwrap(); + + let dxgi_device = { + profiling::scope!("IDXGIDevice::QueryInterface"); + d3d11_device.cast::().map_err(|err| { + log::error!("IDXGIDevice::QueryInterface failed: {err}"); + crate::SurfaceError::Other("IDXGIDevice::QueryInterface") + })? + }; + + let dcomp_device = { + profiling::scope!("DirectComposition::DCompositionCreateDevice"); + unsafe { + DirectComposition::DCompositionCreateDevice::< + _, + DirectComposition::IDCompositionDevice, + >(&dxgi_device) + } + .map_err(|err| { + log::error!("DirectComposition::DCompositionCreateDevice failed: {err}"); + crate::SurfaceError::Other("DirectComposition::DCompositionCreateDevice") + })? + }; + + let target = { + profiling::scope!("IDCompositionDevice::CreateTargetForHwnd"); + unsafe { dcomp_device.CreateTargetForHwnd(*hwnd, false) }.map_err(|err| { + log::error!("IDCompositionDevice::CreateTargetForHwnd failed: {err}"); + crate::SurfaceError::Other("IDCompositionDevice::CreateTargetForHwnd") + })? + }; + + let visual = { + profiling::scope!("IDCompositionDevice::CreateVisual"); + unsafe { dcomp_device.CreateVisual() }.map_err(|err| { + log::error!("IDCompositionDevice::CreateVisual failed: {err}"); + crate::SurfaceError::Other("IDCompositionDevice::CreateVisual") + })? + }; + + { + profiling::scope!("IDCompositionTarget::SetRoot"); + unsafe { target.SetRoot(&visual) }.map_err(|err| { + log::error!("IDCompositionTarget::SetRoot failed: {err}"); + crate::SurfaceError::Other("IDCompositionTarget::SetRoot") + })?; + } + + Ok(InnerState { + visual, + device: dcomp_device, + _target: target, + }) + } +} diff --git a/wgpu-hal/src/dx12/mod.rs b/wgpu-hal/src/dx12/mod.rs index 41ebc549f59..9155c072f77 100644 --- a/wgpu-hal/src/dx12/mod.rs +++ b/wgpu-hal/src/dx12/mod.rs @@ -77,6 +77,7 @@ Otherwise, we pass a range corresponding only to the current bind group. mod adapter; mod command; mod conv; +mod dcomp; mod descriptor; mod device; mod instance; @@ -528,20 +529,13 @@ struct SwapChain { size: wgt::Extent3d, } -struct DCompState { - visual: DirectComposition::IDCompositionVisual, - device: DirectComposition::IDCompositionDevice, - // Must be kept alive but is otherwise unused after initialization. - _target: DirectComposition::IDCompositionTarget, -} - enum SurfaceTarget { /// Borrowed, lifetime externally managed WndHandle(Foundation::HWND), /// `handle` is borrowed, lifetime externally managed VisualFromWndHandle { handle: Foundation::HWND, - dcomp_state: RwLock>, + dcomp_state: Mutex, }, Visual(DirectComposition::IDCompositionVisual), /// Borrowed, lifetime externally managed @@ -1294,103 +1288,8 @@ impl crate::Surface for Surface { handle, dcomp_state, } => { - let mut dcomp_state = dcomp_state.write(); - let dcomp_state = match dcomp_state.as_mut() { - Some(s) => s, - None => { - let mut d3d11_device = None; - { - profiling::scope!("Direct3D11on12::D3D11On12CreateDevice"); - unsafe { - Direct3D11on12::D3D11On12CreateDevice( - &device.raw, - Direct3D11::D3D11_CREATE_DEVICE_BGRA_SUPPORT.0, - None, - None, - 0, - Some(&mut d3d11_device), - None, - None, - ) - } - .map_err(|err| { - log::error!( - "Direct3D11on12::D3D11On12CreateDevice failed: {err}" - ); - crate::SurfaceError::Other( - "Direct3D11on12::D3D11On12CreateDevice", - ) - })?; - } - let d3d11_device = d3d11_device.unwrap(); - - let dxgi_device = { - profiling::scope!("IDXGIDevice::QueryInterface"); - d3d11_device.cast::().map_err(|err| { - log::error!("IDXGIDevice::QueryInterface failed: {err}"); - crate::SurfaceError::Other("IDXGIDevice::QueryInterface") - })? - }; - - let dcomp_device = { - profiling::scope!( - "DirectComposition::DCompositionCreateDevice" - ); - unsafe { - DirectComposition::DCompositionCreateDevice::< - _, - DirectComposition::IDCompositionDevice, - >(&dxgi_device) - }.map_err(|err| { - log::error!( - "DirectComposition::DCompositionCreateDevice failed: {err}" - ); - crate::SurfaceError::Other( - "DirectComposition::DCompositionCreateDevice", - ) - })? - }; - - let target = { - profiling::scope!("IDCompositionDevice::CreateTargetForHwnd"); - unsafe { dcomp_device.CreateTargetForHwnd(*handle, false)} - .map_err(|err| { - log::error!( - "IDCompositionDevice::CreateTargetForHwnd failed: {err}" - ); - crate::SurfaceError::Other( - "IDCompositionDevice::CreateTargetForHwnd", - ) - })? - }; - - let visual = { - profiling::scope!("IDCompositionDevice::CreateVisual"); - unsafe { dcomp_device.CreateVisual() }.map_err(|err| { - log::error!( - "IDCompositionDevice::CreateVisual failed: {err}" - ); - crate::SurfaceError::Other( - "IDCompositionDevice::CreateVisual", - ) - })? - }; - - { - profiling::scope!("IDCompositionTarget::SetRoot"); - unsafe { target.SetRoot(&visual) }.map_err(|err| { - log::error!("IDCompositionTarget::SetRoot failed: {err}"); - crate::SurfaceError::Other("IDCompositionTarget::SetRoot") - })?; - } - - dcomp_state.insert(DCompState { - visual, - device: dcomp_device, - _target: target, - }) - } - }; + let mut dcomp_state = dcomp_state.lock(); + let dcomp_state = dcomp_state.get_or_init(handle, device)?; // Set the new swap chain as the content for the backing visual // and commit the changes to the composition visual tree. { From 8b012f33330d24beb480aa400cb1d5cfb4352728 Mon Sep 17 00:00:00 2001 From: Night_Hunter Date: Wed, 23 Apr 2025 16:38:12 +1200 Subject: [PATCH 05/23] refactor: replace use_dcomp with presentation_system in Dx12BackendOptions --- wgpu-types/src/instance.rs | 51 +++++++++++++++++++++++++++++++++++--- 1 file changed, 47 insertions(+), 4 deletions(-) diff --git a/wgpu-types/src/instance.rs b/wgpu-types/src/instance.rs index f263a2147c2..0cf5dff0732 100644 --- a/wgpu-types/src/instance.rs +++ b/wgpu-types/src/instance.rs @@ -309,8 +309,8 @@ impl GlBackendOptions { pub struct Dx12BackendOptions { /// Which DX12 shader compiler to use. pub shader_compiler: Dx12Compiler, - /// Whether to use DirectComposition for managing presentation. - pub use_dcomp: bool, + /// Presentation system to use. + pub presentation_system: Dx12PresentationSystem, } impl Dx12BackendOptions { @@ -320,9 +320,10 @@ impl Dx12BackendOptions { #[must_use] pub fn from_env_or_default() -> Self { let compiler = Dx12Compiler::from_env().unwrap_or_default(); + let presentation_system = Dx12PresentationSystem::from_env().unwrap_or_default(); Self { shader_compiler: compiler, - use_dcomp: false, + presentation_system, } } @@ -332,9 +333,10 @@ impl Dx12BackendOptions { #[must_use] pub fn with_env(self) -> Self { let shader_compiler = self.shader_compiler.with_env(); + let presentation_system = self.presentation_system.with_env(); Self { shader_compiler, - use_dcomp: false, + presentation_system, } } } @@ -385,6 +387,47 @@ impl NoopBackendOptions { } } +#[derive(Clone, Debug, Default)] +/// Selects which presentation system to use on DX12. +pub enum Dx12PresentationSystem { + /// Use the DXGI presentation system. + #[default] + Dxgi, + /// Use the DirectComposition presentation system. + Dcomp, +} + +impl Dx12PresentationSystem { + /// Choose which presentation system to use from the environment variable `WGPU_DX12_PRESENTATION_SYSTEM`. + /// + /// Valid values, case insensitive: + /// - `Dxgi` + /// - `Dcomp` + #[must_use] + pub fn from_env() -> Option { + let value = crate::env::var("WGPU_DX12_PRESENTATION_SYSTEM") + .as_deref()? + .to_lowercase(); + match value.as_str() { + "dcomp" => Some(Self::Dcomp), + "dxgi" => Some(Self::Dxgi), + _ => None, + } + } + + /// Takes the given presentation system, modifies it based on the `WGPU_DX12_PRESENTATION_SYSTEM` environment variable, and returns the result. + /// + /// See [`from_env`](Self::from_env) for more information. + #[must_use] + pub fn with_env(self) -> Self { + if let Some(presentation_system) = Self::from_env() { + presentation_system + } else { + self + } + } +} + /// DXC shader model. #[derive(Clone, Debug)] #[allow(missing_docs)] From 91d98afcf3ddef2a9d7292087ed4570c3548254c Mon Sep 17 00:00:00 2001 From: Night_Hunter Date: Wed, 23 Apr 2025 16:40:02 +1200 Subject: [PATCH 06/23] refactor: enhance Dx12PresentationSystem with Copy, PartialEq, and Eq traits --- wgpu-types/src/instance.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wgpu-types/src/instance.rs b/wgpu-types/src/instance.rs index 0cf5dff0732..d3ed66db210 100644 --- a/wgpu-types/src/instance.rs +++ b/wgpu-types/src/instance.rs @@ -387,7 +387,7 @@ impl NoopBackendOptions { } } -#[derive(Clone, Debug, Default)] +#[derive(Clone, Debug, Default, Copy, PartialEq, Eq)] /// Selects which presentation system to use on DX12. pub enum Dx12PresentationSystem { /// Use the DXGI presentation system. From bae60c3c0f5c6da6851ddb120334e72108439733 Mon Sep 17 00:00:00 2001 From: Night_Hunter Date: Wed, 23 Apr 2025 16:44:40 +1200 Subject: [PATCH 07/23] refactor: replace use_dcomp with presentation_system in Dx12 backend options --- deno_webgpu/lib.rs | 2 +- tests/src/init.rs | 2 +- wgpu-hal/examples/ray-traced-triangle/main.rs | 2 +- wgpu-hal/src/dx12/instance.rs | 12 ++++++------ wgpu-hal/src/dx12/mod.rs | 5 +++-- 5 files changed, 12 insertions(+), 11 deletions(-) diff --git a/deno_webgpu/lib.rs b/deno_webgpu/lib.rs index e144103552d..d1108e9d072 100644 --- a/deno_webgpu/lib.rs +++ b/deno_webgpu/lib.rs @@ -151,7 +151,7 @@ impl GPU { backend_options: wgpu_types::BackendOptions { dx12: wgpu_types::Dx12BackendOptions { shader_compiler: wgpu_types::Dx12Compiler::Fxc, - use_dcomp: false, + presentation_system: wgpu_types::Dx12PresentationSystem::default(), }, gl: wgpu_types::GlBackendOptions::default(), noop: wgpu_types::NoopBackendOptions::default(), diff --git a/tests/src/init.rs b/tests/src/init.rs index 3fe37b515cf..69cfad51944 100644 --- a/tests/src/init.rs +++ b/tests/src/init.rs @@ -46,7 +46,7 @@ pub fn initialize_instance(backends: wgpu::Backends, params: &TestParameters) -> backend_options: wgpu::BackendOptions { dx12: wgpu::Dx12BackendOptions { shader_compiler: dx12_shader_compiler, - use_dcomp: false, + ..Default::default() }, gl: wgpu::GlBackendOptions { fence_behavior: if cfg!(target_family = "wasm") { diff --git a/wgpu-hal/examples/ray-traced-triangle/main.rs b/wgpu-hal/examples/ray-traced-triangle/main.rs index 8ca470545b5..38086f42cb2 100644 --- a/wgpu-hal/examples/ray-traced-triangle/main.rs +++ b/wgpu-hal/examples/ray-traced-triangle/main.rs @@ -241,7 +241,7 @@ impl Example { backend_options: wgpu_types::BackendOptions { dx12: Dx12BackendOptions { shader_compiler: wgpu_types::Dx12Compiler::default_dynamic_dxc(), - use_dcomp: false, + ..Default::default() }, ..Default::default() }, diff --git a/wgpu-hal/src/dx12/instance.rs b/wgpu-hal/src/dx12/instance.rs index 61b591be9e4..1f60f843bb1 100644 --- a/wgpu-hal/src/dx12/instance.rs +++ b/wgpu-hal/src/dx12/instance.rs @@ -108,7 +108,7 @@ impl crate::Instance for super::Instance { factory, factory_media, library: Arc::new(lib_main), - use_dcomp: desc.backend_options.dx12.use_dcomp, + presentation_system: desc.backend_options.dx12.presentation_system, _lib_dxgi: lib_dxgi, supports_allow_tearing, flags: desc.flags, @@ -125,14 +125,14 @@ impl crate::Instance for super::Instance { raw_window_handle::RawWindowHandle::Win32(handle) => { // https://github.com/rust-windowing/raw-window-handle/issues/171 let handle = Foundation::HWND(handle.hwnd.get() as *mut _); - let target = if self.use_dcomp { - SurfaceTarget::VisualFromWndHandle { + let target = match self.presentation_system { + wgt::Dx12PresentationSystem::Dxgi => SurfaceTarget::WndHandle(handle), + wgt::Dx12PresentationSystem::Dcomp => SurfaceTarget::VisualFromWndHandle { handle, dcomp_state: Default::default(), - } - } else { - SurfaceTarget::WndHandle(handle) + }, }; + Ok(super::Surface { factory: self.factory.clone(), factory_media: self.factory_media.clone(), diff --git a/wgpu-hal/src/dx12/mod.rs b/wgpu-hal/src/dx12/mod.rs index 9155c072f77..833df28b40a 100644 --- a/wgpu-hal/src/dx12/mod.rs +++ b/wgpu-hal/src/dx12/mod.rs @@ -92,11 +92,12 @@ use std::{borrow::ToOwned as _, ffi, fmt, mem, num::NonZeroU32, ops::Deref, sync use arrayvec::ArrayVec; use gpu_allocator::d3d12::Allocator; use parking_lot::{Mutex, RwLock}; +use wgt::Dx12PresentationSystem; use windows::{ core::{Free, Interface}, Win32::{ Foundation, - Graphics::{Direct3D, Direct3D11, Direct3D11on12, Direct3D12, DirectComposition, Dxgi}, + Graphics::{Direct3D, Direct3D12, DirectComposition, Dxgi}, System::Threading, }, }; @@ -459,7 +460,7 @@ pub struct Instance { factory_media: Option, library: Arc, supports_allow_tearing: bool, - use_dcomp: bool, + presentation_system: Dx12PresentationSystem, _lib_dxgi: DxgiLib, flags: wgt::InstanceFlags, dxc_container: Option>, From 32ce5237fb66def5380e35cebae7e03eb0beec5d Mon Sep 17 00:00:00 2001 From: Night_Hunter Date: Wed, 23 Apr 2025 16:48:20 +1200 Subject: [PATCH 08/23] refactor: update Dx12BackendOptions to use presentation_system instead of use_dcomp --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5ba9a8477ae..49e6393023a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -47,7 +47,7 @@ Bottom level categories: - Add Dcomp support to DX12 backend. By @n1ght-hunter in [#7550](https://github.com/gfx-rs/wgpu/pull/7550). ```diff -pub struct Dx12BackendOptions { pub shader_compiler: Dx12Compiler } -+pub struct Dx12BackendOptions { pub shader_compiler: Dx12Compiler, pub use_dcomp: bool } ++pub struct Dx12BackendOptions { pub shader_compiler: Dx12Compiler, pub presentation_system: Dx12PresentationSystem } ``` #### Naga From 73579d37c50f2fe7474e745183ee004170a9ff6b Mon Sep 17 00:00:00 2001 From: Night_Hunter Date: Sat, 2 Aug 2025 00:40:11 +1200 Subject: [PATCH 09/23] refactor(dx12): update DirectComposition device creation to use DCompositionCreateDevice2 --- wgpu-hal/src/dx12/dcomp.rs | 34 ++-------------------------------- 1 file changed, 2 insertions(+), 32 deletions(-) diff --git a/wgpu-hal/src/dx12/dcomp.rs b/wgpu-hal/src/dx12/dcomp.rs index 6d66e1d9c3e..53b3e1c5318 100644 --- a/wgpu-hal/src/dx12/dcomp.rs +++ b/wgpu-hal/src/dx12/dcomp.rs @@ -33,43 +33,13 @@ impl InnerState { /// Creates a DirectComposition device and a target for the given window handle. /// From a Direct3D 12 device, it creates a Direct3D 11 device and then a DirectComposition device. pub unsafe fn init(hwnd: &HWND, device: &super::Device) -> Result { - let mut d3d11_device = None; - { - profiling::scope!("Direct3D11on12::D3D11On12CreateDevice"); - unsafe { - Direct3D11on12::D3D11On12CreateDevice( - &device.raw, - Direct3D11::D3D11_CREATE_DEVICE_BGRA_SUPPORT.0, - None, - None, - 0, - Some(&mut d3d11_device), - None, - None, - ) - } - .map_err(|err| { - log::error!("Direct3D11on12::D3D11On12CreateDevice failed: {err}"); - crate::SurfaceError::Other("Direct3D11on12::D3D11On12CreateDevice") - })?; - } - let d3d11_device = d3d11_device.unwrap(); - - let dxgi_device = { - profiling::scope!("IDXGIDevice::QueryInterface"); - d3d11_device.cast::().map_err(|err| { - log::error!("IDXGIDevice::QueryInterface failed: {err}"); - crate::SurfaceError::Other("IDXGIDevice::QueryInterface") - })? - }; - let dcomp_device = { profiling::scope!("DirectComposition::DCompositionCreateDevice"); unsafe { - DirectComposition::DCompositionCreateDevice::< + DirectComposition::DCompositionCreateDevice2::< _, DirectComposition::IDCompositionDevice, - >(&dxgi_device) + >(None) } .map_err(|err| { log::error!("DirectComposition::DCompositionCreateDevice failed: {err}"); From 830bf2bebd01e8ffce6d8f9ef3aa375b1cbfab02 Mon Sep 17 00:00:00 2001 From: Night_Hunter Date: Sat, 2 Aug 2025 00:43:23 +1200 Subject: [PATCH 10/23] cleanup dcomp create device types --- wgpu-hal/src/dx12/dcomp.rs | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/wgpu-hal/src/dx12/dcomp.rs b/wgpu-hal/src/dx12/dcomp.rs index 53b3e1c5318..334a6e8287a 100644 --- a/wgpu-hal/src/dx12/dcomp.rs +++ b/wgpu-hal/src/dx12/dcomp.rs @@ -33,13 +33,10 @@ impl InnerState { /// Creates a DirectComposition device and a target for the given window handle. /// From a Direct3D 12 device, it creates a Direct3D 11 device and then a DirectComposition device. pub unsafe fn init(hwnd: &HWND, device: &super::Device) -> Result { - let dcomp_device = { + let dcomp_device: DirectComposition::IDCompositionDevice = { profiling::scope!("DirectComposition::DCompositionCreateDevice"); unsafe { - DirectComposition::DCompositionCreateDevice2::< - _, - DirectComposition::IDCompositionDevice, - >(None) + DirectComposition::DCompositionCreateDevice2(None) } .map_err(|err| { log::error!("DirectComposition::DCompositionCreateDevice failed: {err}"); From f40d9b536ec0a5d8108d9e4c289b6d784d751e63 Mon Sep 17 00:00:00 2001 From: Night_Hunter Date: Sat, 2 Aug 2025 00:46:24 +1200 Subject: [PATCH 11/23] clean dcomp code --- wgpu-hal/src/dx12/dcomp.rs | 16 +++++----------- wgpu-hal/src/dx12/mod.rs | 2 +- 2 files changed, 6 insertions(+), 12 deletions(-) diff --git a/wgpu-hal/src/dx12/dcomp.rs b/wgpu-hal/src/dx12/dcomp.rs index 334a6e8287a..f2d4d3f50b9 100644 --- a/wgpu-hal/src/dx12/dcomp.rs +++ b/wgpu-hal/src/dx12/dcomp.rs @@ -1,8 +1,4 @@ -use windows::Win32::{ - Foundation::HWND, - Graphics::{Direct3D11, Direct3D11on12, DirectComposition, Dxgi}, -}; -use windows_core::Interface as _; +use windows::Win32::{Foundation::HWND, Graphics::DirectComposition}; #[derive(Default)] pub struct DCompState { @@ -10,7 +6,9 @@ pub struct DCompState { } impl DCompState { - pub fn get_or_init( + /// This will create a DirectComposition device and a target for the window handle if not already initialized. + /// If the device is already initialized, it will return the existing state. + pub unsafe fn get_or_init( &mut self, hwnd: &HWND, device: &super::Device, @@ -31,14 +29,10 @@ pub struct InnerState { impl InnerState { /// Creates a DirectComposition device and a target for the given window handle. - /// From a Direct3D 12 device, it creates a Direct3D 11 device and then a DirectComposition device. pub unsafe fn init(hwnd: &HWND, device: &super::Device) -> Result { let dcomp_device: DirectComposition::IDCompositionDevice = { profiling::scope!("DirectComposition::DCompositionCreateDevice"); - unsafe { - DirectComposition::DCompositionCreateDevice2(None) - } - .map_err(|err| { + unsafe { DirectComposition::DCompositionCreateDevice2(None) }.map_err(|err| { log::error!("DirectComposition::DCompositionCreateDevice failed: {err}"); crate::SurfaceError::Other("DirectComposition::DCompositionCreateDevice") })? diff --git a/wgpu-hal/src/dx12/mod.rs b/wgpu-hal/src/dx12/mod.rs index 1bee0a04779..3db92c3744b 100644 --- a/wgpu-hal/src/dx12/mod.rs +++ b/wgpu-hal/src/dx12/mod.rs @@ -1336,7 +1336,7 @@ impl crate::Surface for Surface { dcomp_state, } => { let mut dcomp_state = dcomp_state.lock(); - let dcomp_state = dcomp_state.get_or_init(handle, device)?; + let dcomp_state = unsafe { dcomp_state.get_or_init(handle, device) }?; // Set the new swap chain as the content for the backing visual // and commit the changes to the composition visual tree. { From 2302705822fb27bd4a3f22f2bd2dd2308adb41cb Mon Sep 17 00:00:00 2001 From: Night_Hunter Date: Sat, 2 Aug 2025 00:48:16 +1200 Subject: [PATCH 12/23] refactor(dx12): remove unused Direct3D 11 dependencies from Cargo.toml --- wgpu-hal/Cargo.toml | 2 -- 1 file changed, 2 deletions(-) diff --git a/wgpu-hal/Cargo.toml b/wgpu-hal/Cargo.toml index 0af90108650..94dc0e07e0c 100644 --- a/wgpu-hal/Cargo.toml +++ b/wgpu-hal/Cargo.toml @@ -145,8 +145,6 @@ dx12 = [ "windows/Win32_Graphics_Direct3D_Dxc", "windows/Win32_Graphics_Direct3D", "windows/Win32_Graphics_Direct3D12", - "windows/Win32_Graphics_Direct3D11", - "windows/Win32_Graphics_Direct3D11on12", "windows/Win32_Graphics_DirectComposition", "windows/Win32_Graphics_Dxgi_Common", "windows/Win32_Security", From 504dfa11490d9dfd31148b7685962302cd3fd030 Mon Sep 17 00:00:00 2001 From: Night_Hunter Date: Sat, 2 Aug 2025 00:49:40 +1200 Subject: [PATCH 13/23] refactor(dx12): remove unnecessary device parameter from DirectComposition initialization --- wgpu-hal/src/dx12/dcomp.rs | 5 ++--- wgpu-hal/src/dx12/mod.rs | 2 +- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/wgpu-hal/src/dx12/dcomp.rs b/wgpu-hal/src/dx12/dcomp.rs index f2d4d3f50b9..a9a8da83c5b 100644 --- a/wgpu-hal/src/dx12/dcomp.rs +++ b/wgpu-hal/src/dx12/dcomp.rs @@ -11,10 +11,9 @@ impl DCompState { pub unsafe fn get_or_init( &mut self, hwnd: &HWND, - device: &super::Device, ) -> Result<&mut InnerState, crate::SurfaceError> { if self.inner.is_none() { - self.inner = Some(unsafe { InnerState::init(hwnd, device) }?); + self.inner = Some(unsafe { InnerState::init(hwnd) }?); } Ok(self.inner.as_mut().unwrap()) } @@ -29,7 +28,7 @@ pub struct InnerState { impl InnerState { /// Creates a DirectComposition device and a target for the given window handle. - pub unsafe fn init(hwnd: &HWND, device: &super::Device) -> Result { + pub unsafe fn init(hwnd: &HWND) -> Result { let dcomp_device: DirectComposition::IDCompositionDevice = { profiling::scope!("DirectComposition::DCompositionCreateDevice"); unsafe { DirectComposition::DCompositionCreateDevice2(None) }.map_err(|err| { diff --git a/wgpu-hal/src/dx12/mod.rs b/wgpu-hal/src/dx12/mod.rs index 3db92c3744b..4bcb41ea819 100644 --- a/wgpu-hal/src/dx12/mod.rs +++ b/wgpu-hal/src/dx12/mod.rs @@ -1336,7 +1336,7 @@ impl crate::Surface for Surface { dcomp_state, } => { let mut dcomp_state = dcomp_state.lock(); - let dcomp_state = unsafe { dcomp_state.get_or_init(handle, device) }?; + let dcomp_state = unsafe { dcomp_state.get_or_init(handle) }?; // Set the new swap chain as the content for the backing visual // and commit the changes to the composition visual tree. { From 62758fe942029a40710556bbf0d45d4296594ce9 Mon Sep 17 00:00:00 2001 From: Night_Hunter Date: Fri, 15 Aug 2025 01:06:31 +1200 Subject: [PATCH 14/23] Update wgpu-types/src/instance.rs Co-authored-by: Connor Fitzgerald --- wgpu-types/src/instance.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wgpu-types/src/instance.rs b/wgpu-types/src/instance.rs index 91d0293564c..c5da9563a38 100644 --- a/wgpu-types/src/instance.rs +++ b/wgpu-types/src/instance.rs @@ -444,7 +444,7 @@ pub enum Dx12PresentationSystem { #[default] Dxgi, /// Use the DirectComposition presentation system. - Dcomp, + DirectComposition, } impl Dx12PresentationSystem { From 25f68fa7e7fcadaf5c09ec7df7178682ee91d5f4 Mon Sep 17 00:00:00 2001 From: Night_Hunter Date: Fri, 15 Aug 2025 01:06:43 +1200 Subject: [PATCH 15/23] Update wgpu-types/src/instance.rs Co-authored-by: Connor Fitzgerald --- wgpu-types/src/instance.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/wgpu-types/src/instance.rs b/wgpu-types/src/instance.rs index c5da9563a38..59865cf149d 100644 --- a/wgpu-types/src/instance.rs +++ b/wgpu-types/src/instance.rs @@ -438,8 +438,8 @@ impl NoopBackendOptions { } #[derive(Clone, Debug, Default, Copy, PartialEq, Eq)] -/// Selects which presentation system to use on DX12. -pub enum Dx12PresentationSystem { +/// Selects which kind of swapchain to use on DX12. +pub enum Dx12SwapchainKind { /// Use the DXGI presentation system. #[default] Dxgi, From 7b5d124425ec92cbcb9c6c6b888940769c9d9aa7 Mon Sep 17 00:00:00 2001 From: Night_Hunter Date: Fri, 15 Aug 2025 01:06:51 +1200 Subject: [PATCH 16/23] Update wgpu-types/src/instance.rs Co-authored-by: Connor Fitzgerald --- wgpu-types/src/instance.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/wgpu-types/src/instance.rs b/wgpu-types/src/instance.rs index 59865cf149d..6e6a511b916 100644 --- a/wgpu-types/src/instance.rs +++ b/wgpu-types/src/instance.rs @@ -440,7 +440,9 @@ impl NoopBackendOptions { #[derive(Clone, Debug, Default, Copy, PartialEq, Eq)] /// Selects which kind of swapchain to use on DX12. pub enum Dx12SwapchainKind { - /// Use the DXGI presentation system. + /// Use a DXGI swapchain made directly from the window's HWND. + /// + /// This supports fullscreen optimization, making borderless windows just as efficient as exclusive fullscreen. It does not support transparent windows. #[default] Dxgi, /// Use the DirectComposition presentation system. From eab2de642a42a1144f442f1f970a766bb3bf55c0 Mon Sep 17 00:00:00 2001 From: Night_Hunter Date: Fri, 15 Aug 2025 01:07:01 +1200 Subject: [PATCH 17/23] Update wgpu-types/src/instance.rs Co-authored-by: Connor Fitzgerald --- wgpu-types/src/instance.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/wgpu-types/src/instance.rs b/wgpu-types/src/instance.rs index 6e6a511b916..6427c7972bb 100644 --- a/wgpu-types/src/instance.rs +++ b/wgpu-types/src/instance.rs @@ -445,7 +445,9 @@ pub enum Dx12SwapchainKind { /// This supports fullscreen optimization, making borderless windows just as efficient as exclusive fullscreen. It does not support transparent windows. #[default] Dxgi, - /// Use the DirectComposition presentation system. + /// Use a DXGI swapchain made from a DirectComposition visual made from the window. + /// + /// This supports transparent windows, but does not support fullscreen optimization. DirectComposition, } From a9ddf45bbaa012f5e601ca2384ae37eea8493a63 Mon Sep 17 00:00:00 2001 From: Night_Hunter Date: Fri, 15 Aug 2025 01:07:10 +1200 Subject: [PATCH 18/23] Update CHANGELOG.md Co-authored-by: Connor Fitzgerald --- CHANGELOG.md | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f75905b8fdc..77fd8367805 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -42,14 +42,17 @@ Bottom level categories: ### Major Changes -#### DX12 +#### Builtin Support for DirectComposition/DXGI swapchains in DX12 + +By selecting DirectComposition, the compositor cannot optimize your Swapchain as much, but you can support transparent windows. -- Add Dcomp support to DX12 backend. By @n1ght-hunter in [#7550](https://github.com/gfx-rs/wgpu/pull/7550). ```diff -pub struct Dx12BackendOptions { pub shader_compiler: Dx12Compiler } +pub struct Dx12BackendOptions { pub shader_compiler: Dx12Compiler, pub presentation_system: Dx12PresentationSystem } ``` +By @n1ght-hunter in [#7550](https://github.com/gfx-rs/wgpu/pull/7550). + #### General #### `EXPERIMENTAL_RAY_TRACING_ACCELERATION_STRUCTURE` has been merged into `EXPERIMENTAL_RAY_QUERY` From 55659a13ff0b98bb2a9c457d568fcdcd3c0f7c3a Mon Sep 17 00:00:00 2001 From: Night_Hunter Date: Fri, 15 Aug 2025 01:07:40 +1200 Subject: [PATCH 19/23] Update CHANGELOG.md Co-authored-by: Connor Fitzgerald --- CHANGELOG.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 77fd8367805..306f2f3c493 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -53,8 +53,6 @@ By selecting DirectComposition, the compositor cannot optimize your Swapchain as By @n1ght-hunter in [#7550](https://github.com/gfx-rs/wgpu/pull/7550). -#### General - #### `EXPERIMENTAL_RAY_TRACING_ACCELERATION_STRUCTURE` has been merged into `EXPERIMENTAL_RAY_QUERY` We have merged the acceleration structure feature into the `RayQuery` feature. This is to help work around an AMD driver bug and reduce the feature complexity of ray tracing. In the future when ray tracing pipelines are implemented, if either feature is enabled, acceleration structures will be available. From 783e7307f2f02e32d4f4c806c75e773f369db151 Mon Sep 17 00:00:00 2001 From: Night_Hunter Date: Fri, 15 Aug 2025 01:20:14 +1200 Subject: [PATCH 20/23] fmt --- wgpu-hal/src/dx12/instance.rs | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/wgpu-hal/src/dx12/instance.rs b/wgpu-hal/src/dx12/instance.rs index b6ba3f1dcb2..1c7b1d54713 100644 --- a/wgpu-hal/src/dx12/instance.rs +++ b/wgpu-hal/src/dx12/instance.rs @@ -125,10 +125,12 @@ impl crate::Instance for super::Instance { let handle = Foundation::HWND(handle.hwnd.get() as *mut _); let target = match self.presentation_system { wgt::Dx12SwapchainKind::Dxgi => SurfaceTarget::WndHandle(handle), - wgt::Dx12SwapchainKind::DirectComposition => SurfaceTarget::VisualFromWndHandle { - handle, - dcomp_state: Default::default(), - }, + wgt::Dx12SwapchainKind::DirectComposition => { + SurfaceTarget::VisualFromWndHandle { + handle, + dcomp_state: Default::default(), + } + } }; Ok(super::Surface { From 1a9ff41090611b14b71ba14c539687de4f26ba1a Mon Sep 17 00:00:00 2001 From: Night_Hunter Date: Fri, 15 Aug 2025 16:12:00 +1200 Subject: [PATCH 21/23] Update CHANGELOG.md Co-authored-by: Marijn Suijten --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0b40eec8e07..c7b705c800b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -46,6 +46,8 @@ Bottom level categories: By selecting DirectComposition, the compositor cannot optimize your Swapchain as much, but you can support transparent windows. +This creates a single `IDCompositionVisual` over the entire window that is used by the `Surface`. If a user wants to manage the composition tree themselves, they should create their own device and composition, and pass the relevant visual down into `wgpu` via `IDCompositionTarget::CompositionVisual` or `IDCompositionTarget::SurfaceHandle`. + ```diff -pub struct Dx12BackendOptions { pub shader_compiler: Dx12Compiler } +pub struct Dx12BackendOptions { pub shader_compiler: Dx12Compiler, pub presentation_system: Dx12SwapchainKind } From 1fd08cfff7559102660ee77d9b186c0fdf44d515 Mon Sep 17 00:00:00 2001 From: Night_Hunter Date: Tue, 2 Sep 2025 19:56:55 +1200 Subject: [PATCH 22/23] use a single scope profle for all of DCompState init --- wgpu-hal/src/dx12/dcomp.rs | 35 +++++++++++++---------------------- 1 file changed, 13 insertions(+), 22 deletions(-) diff --git a/wgpu-hal/src/dx12/dcomp.rs b/wgpu-hal/src/dx12/dcomp.rs index a9a8da83c5b..a6bc83352a6 100644 --- a/wgpu-hal/src/dx12/dcomp.rs +++ b/wgpu-hal/src/dx12/dcomp.rs @@ -29,37 +29,28 @@ pub struct InnerState { impl InnerState { /// Creates a DirectComposition device and a target for the given window handle. pub unsafe fn init(hwnd: &HWND) -> Result { + profiling::scope!("DCompState::init"); let dcomp_device: DirectComposition::IDCompositionDevice = { - profiling::scope!("DirectComposition::DCompositionCreateDevice"); unsafe { DirectComposition::DCompositionCreateDevice2(None) }.map_err(|err| { log::error!("DirectComposition::DCompositionCreateDevice failed: {err}"); crate::SurfaceError::Other("DirectComposition::DCompositionCreateDevice") })? }; - let target = { - profiling::scope!("IDCompositionDevice::CreateTargetForHwnd"); - unsafe { dcomp_device.CreateTargetForHwnd(*hwnd, false) }.map_err(|err| { - log::error!("IDCompositionDevice::CreateTargetForHwnd failed: {err}"); - crate::SurfaceError::Other("IDCompositionDevice::CreateTargetForHwnd") - })? - }; + let target = unsafe { dcomp_device.CreateTargetForHwnd(*hwnd, false) }.map_err(|err| { + log::error!("IDCompositionDevice::CreateTargetForHwnd failed: {err}"); + crate::SurfaceError::Other("IDCompositionDevice::CreateTargetForHwnd") + })?; - let visual = { - profiling::scope!("IDCompositionDevice::CreateVisual"); - unsafe { dcomp_device.CreateVisual() }.map_err(|err| { - log::error!("IDCompositionDevice::CreateVisual failed: {err}"); - crate::SurfaceError::Other("IDCompositionDevice::CreateVisual") - })? - }; + let visual = unsafe { dcomp_device.CreateVisual() }.map_err(|err| { + log::error!("IDCompositionDevice::CreateVisual failed: {err}"); + crate::SurfaceError::Other("IDCompositionDevice::CreateVisual") + })?; - { - profiling::scope!("IDCompositionTarget::SetRoot"); - unsafe { target.SetRoot(&visual) }.map_err(|err| { - log::error!("IDCompositionTarget::SetRoot failed: {err}"); - crate::SurfaceError::Other("IDCompositionTarget::SetRoot") - })?; - } + unsafe { target.SetRoot(&visual) }.map_err(|err| { + log::error!("IDCompositionTarget::SetRoot failed: {err}"); + crate::SurfaceError::Other("IDCompositionTarget::SetRoot") + })?; Ok(InnerState { visual, From e5589fd8149c8bfb97850392e7e5f7086c0c309d Mon Sep 17 00:00:00 2001 From: Night_Hunter Date: Tue, 2 Sep 2025 19:58:21 +1200 Subject: [PATCH 23/23] Allow "directcomposition" as an alias for "dcomp" in Dx12SwapchainKind --- wgpu-types/src/instance.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wgpu-types/src/instance.rs b/wgpu-types/src/instance.rs index 0c9e1581b72..1c50f29a98f 100644 --- a/wgpu-types/src/instance.rs +++ b/wgpu-types/src/instance.rs @@ -470,7 +470,7 @@ impl Dx12SwapchainKind { .as_deref()? .to_lowercase(); match value.as_str() { - "dcomp" => Some(Self::DirectComposition), + "dcomp" | "directcomposition" => Some(Self::DirectComposition), "dxgi" => Some(Self::Dxgi), _ => None, }