Skip to content
Open
Show file tree
Hide file tree
Changes from 5 commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
e6d7e5f
add dx12 dcomp option to backend options
n1ght-hunter Apr 13, 2025
c328699
impl dcomp for the dx12 backend
n1ght-hunter Apr 13, 2025
3f91a00
Merge branch 'gfx-rs:trunk' into dev/windows-os-transparent
n1ght-hunter Apr 13, 2025
b8131bf
Merge branch 'gfx-rs:trunk' into dev/windows-os-transparent
n1ght-hunter Apr 16, 2025
1f70a9a
Add Dcomp support to DX12 backend in changelog
n1ght-hunter Apr 16, 2025
60a747c
move decomp to another module
n1ght-hunter Apr 23, 2025
8b012f3
refactor: replace use_dcomp with presentation_system in Dx12BackendOp…
n1ght-hunter Apr 23, 2025
91d98af
refactor: enhance Dx12PresentationSystem with Copy, PartialEq, and Eq…
n1ght-hunter Apr 23, 2025
bae60c3
refactor: replace use_dcomp with presentation_system in Dx12 backend …
n1ght-hunter Apr 23, 2025
194a685
Merge branch 'trunk' into dev/windows-os-transparent
n1ght-hunter Apr 23, 2025
32ce523
refactor: update Dx12BackendOptions to use presentation_system instea…
n1ght-hunter Apr 23, 2025
157c1c6
Merge branch 'dev/windows-os-transparent' of https://github.com/n1ght…
n1ght-hunter Apr 23, 2025
cd41a6e
Merge branch 'trunk' into dev/windows-os-transparent
n1ght-hunter Apr 27, 2025
73579d3
refactor(dx12): update DirectComposition device creation to use DComp…
n1ght-hunter Aug 1, 2025
cae67ca
Merge branch 'trunk' into dev/windows-os-transparent
n1ght-hunter Aug 1, 2025
830bf2b
cleanup dcomp create device types
n1ght-hunter Aug 1, 2025
f40d9b5
clean dcomp code
n1ght-hunter Aug 1, 2025
2302705
refactor(dx12): remove unused Direct3D 11 dependencies from Cargo.toml
n1ght-hunter Aug 1, 2025
504dfa1
refactor(dx12): remove unnecessary device parameter from DirectCompos…
n1ght-hunter Aug 1, 2025
62758fe
Update wgpu-types/src/instance.rs
n1ght-hunter Aug 14, 2025
25f68fa
Update wgpu-types/src/instance.rs
n1ght-hunter Aug 14, 2025
7b5d124
Update wgpu-types/src/instance.rs
n1ght-hunter Aug 14, 2025
eab2de6
Update wgpu-types/src/instance.rs
n1ght-hunter Aug 14, 2025
a9ddf45
Update CHANGELOG.md
n1ght-hunter Aug 14, 2025
55659a1
Update CHANGELOG.md
n1ght-hunter Aug 14, 2025
92afbbc
Merge branch 'trunk' into dev/windows-os-transparent
n1ght-hunter Aug 14, 2025
783e730
fmt
n1ght-hunter Aug 14, 2025
1a9ff41
Update CHANGELOG.md
n1ght-hunter Aug 15, 2025
1fd08cf
use a single scope profle for all of DCompState init
n1ght-hunter Sep 2, 2025
e5589fd
Allow "directcomposition" as an alias for "dcomp" in Dx12SwapchainKind
n1ght-hunter Sep 2, 2025
bdb0a22
Merge branch 'trunk' into dev/windows-os-transparent
n1ght-hunter Sep 2, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
1 change: 1 addition & 0 deletions deno_webgpu/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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(),
Expand Down
1 change: 1 addition & 0 deletions tests/src/init.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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") {
Expand Down
2 changes: 2 additions & 0 deletions wgpu-hal/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
1 change: 1 addition & 0 deletions wgpu-hal/examples/ray-traced-triangle/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -241,6 +241,7 @@ impl<A: hal::Api> Example<A> {
backend_options: wgpu_types::BackendOptions {
dx12: Dx12BackendOptions {
shader_compiler: wgpu_types::Dx12Compiler::default_dynamic_dxc(),
use_dcomp: false,
},
..Default::default()
},
Expand Down
6 changes: 5 additions & 1 deletion wgpu-hal/src/dx12/adapter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -843,7 +843,10 @@ impl crate::Adapter for super::Adapter {
) -> Option<crate::SurfaceCapabilities> {
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()
{
Expand Down Expand Up @@ -887,6 +890,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,
Expand Down
26 changes: 19 additions & 7 deletions wgpu-hal/src/dx12/instance.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -121,14 +122,25 @@ impl crate::Instance for super::Instance {
window_handle: raw_window_handle::RawWindowHandle,
) -> Result<super::Surface, crate::InstanceError> {
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"
))),
Expand Down
142 changes: 140 additions & 2 deletions wgpu-hal/src/dx12/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
},
};
Expand Down Expand Up @@ -458,6 +458,7 @@ pub struct Instance {
factory_media: Option<Dxgi::IDXGIFactoryMedia>,
library: Arc<D3D12Lib>,
supports_allow_tearing: bool,
use_dcomp: bool,
_lib_dxgi: DxgiLib,
flags: wgt::InstanceFlags,
dxc_container: Option<Arc<shader_compilation::DxcContainer>>,
Expand Down Expand Up @@ -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<Option<DCompState>>,
},
Visual(DirectComposition::IDCompositionVisual),
/// Borrowed, lifetime externally managed
SurfaceHandle(Foundation::HANDLE),
Expand Down Expand Up @@ -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(
Expand Down Expand Up @@ -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::<Dxgi::IDXGIDevice>().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}");
Expand Down Expand Up @@ -1312,6 +1449,7 @@ impl crate::Surface for Surface {
.into_device_result("MakeWindowAssociation")?;
}
SurfaceTarget::Visual(_)
| SurfaceTarget::VisualFromWndHandle { .. }
| SurfaceTarget::SurfaceHandle(_)
| SurfaceTarget::SwapChainPanel(_) => {}
}
Expand Down
8 changes: 7 additions & 1 deletion wgpu-types/src/instance.rs
Original file line number Diff line number Diff line change
Expand Up @@ -309,6 +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,
}

impl Dx12BackendOptions {
Expand All @@ -320,6 +322,7 @@ impl Dx12BackendOptions {
let compiler = Dx12Compiler::from_env().unwrap_or_default();
Self {
shader_compiler: compiler,
use_dcomp: false,
}
}

Expand All @@ -329,7 +332,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,
}
}
}

Expand Down
Loading