Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
1 change: 1 addition & 0 deletions deno_webgpu/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -394,6 +394,7 @@ pub fn op_webgpu_request_adapter(
backend_options: wgpu_types::BackendOptions {
dx12: wgpu_types::Dx12BackendOptions {
shader_compiler: wgpu_types::Dx12Compiler::Fxc,
use_dcomp: false,
},
gl: wgpu_types::GlBackendOptions {
gles_minor_version: wgpu_types::Gles3MinorVersion::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 @@ -43,6 +43,7 @@ pub fn initialize_instance(backends: wgpu::Backends, force_fxc: bool) -> Instanc
backend_options: wgpu::BackendOptions {
dx12: wgpu::Dx12BackendOptions {
shader_compiler: dx12_shader_compiler,
use_dcomp: false,
},
gl: wgpu::GlBackendOptions { gles_minor_version },
},
Expand Down
1 change: 1 addition & 0 deletions wgpu-core/src/instance.rs
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ impl Instance {
.dx12
.shader_compiler
.clone(),
dx12_use_dcomp: instance_desc.backend_options.dx12.use_dcomp,
gles_minor_version: instance_desc.backend_options.gl.gles_minor_version,
};

Expand Down
2 changes: 2 additions & 0 deletions wgpu-hal/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,8 @@ dx12 = [
"windows/Win32_Graphics_Direct3D_Fxc",
"windows/Win32_Graphics_Direct3D_Dxc",
"windows/Win32_Graphics_Direct3D",
"windows/Win32_Graphics_Direct3D11",
"windows/Win32_Graphics_Direct3D11on12",
"windows/Win32_Graphics_Direct3D12",
"windows/Win32_Graphics_DirectComposition",
"windows/Win32_Graphics_Dxgi_Common",
Expand Down
1 change: 1 addition & 0 deletions wgpu-hal/examples/halmark/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@ impl<A: hal::Api> Example<A> {
flags: wgt::InstanceFlags::from_build_config().with_env(),
// Can't rely on having DXC available, so use FXC instead
dx12_shader_compiler: wgt::Dx12Compiler::Fxc,
dx12_use_dcomp: false,
gles_minor_version: wgt::Gles3MinorVersion::default(),
};
let instance = unsafe { A::Instance::init(&instance_desc)? };
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 @@ -243,6 +243,7 @@ impl<A: hal::Api> Example<A> {
dxc_path: "dxcompiler.dll".to_string(),
dxil_path: "dxil.dll".to_string(),
},
dx12_use_dcomp: false,
gles_minor_version: wgt::Gles3MinorVersion::default(),
};
let instance = unsafe { A::Instance::init(&instance_desc)? };
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 @@ -787,7 +787,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 @@ -831,6 +834,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
27 changes: 20 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 {
library: Arc::new(lib_main),
_lib_dxgi: lib_dxgi,
supports_allow_tearing,
use_dcomp: desc.dx12_use_dcomp,
flags: desc.flags,
dxc_container,
})
Expand All @@ -119,14 +120,26 @@ 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
84 changes: 82 additions & 2 deletions wgpu-hal/src/dx12/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,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 @@ -410,6 +410,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 @@ -479,9 +480,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 @@ -1137,7 +1150,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 @@ -1184,6 +1199,70 @@ impl crate::Surface for Surface {

match &self.target {
SurfaceTarget::WndHandle(_) | SurfaceTarget::SurfaceHandle(_) => {}
SurfaceTarget::VisualFromWndHandle {
handle,
dcomp_state,
} => unsafe {
macro_rules! call {
($name:literal, $e:expr) => {{
profiling::scope!($name);
($e).map_err(|_| crate::SurfaceError::Other($name))?
}};
}

// Initialize the window-linked DirectComposition state
// if we haven't done so already.
let mut dcomp_state = dcomp_state.write();
let dcomp_state = match dcomp_state.as_mut() {
Some(s) => s,
None => {
let mut d3d11_device = None;
call!(
"Direct3D11on12::D3D11On12CreateDevice",
Direct3D11on12::D3D11On12CreateDevice(
&device.raw,
Direct3D11::D3D11_CREATE_DEVICE_BGRA_SUPPORT.0,
None,
None,
0,
Some(&mut d3d11_device),
None,
None,
)
);
let d3d11_device = d3d11_device.unwrap();
let dxgi_device: Dxgi::IDXGIDevice =
call!("IDXGIDevice::QueryInterface", d3d11_device.cast());
let dcomp_device: DirectComposition::IDCompositionDevice = call!(
"DirectComposition::DCompositionCreateDevice",
DirectComposition::DCompositionCreateDevice(&dxgi_device)
);
let target = call!(
"IDCompositionDevice::CreateTargetForHwnd",
dcomp_device.CreateTargetForHwnd(*handle, false)
);
let visual = call!(
"IDCompositionDevice::CreateVisual",
dcomp_device.CreateVisual()
);
call!("IDCompositionTarget::SetRoot", target.SetRoot(&visual));

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.
call!(
"IDCompositionVisual::SetContent",
dcomp_state.visual.SetContent(&swap_chain1)
);
call!("IDCompositionDevice::Commit", dcomp_state.device.Commit());
},
SurfaceTarget::Visual(visual) => {
if let Err(err) = unsafe { visual.SetContent(&swap_chain1) } {
log::error!("Unable to SetContent: {err}");
Expand Down Expand Up @@ -1221,6 +1300,7 @@ impl crate::Surface for Surface {
.into_device_result("MakeWindowAssociation")?;
}
SurfaceTarget::Visual(_)
| SurfaceTarget::VisualFromWndHandle { .. }
| SurfaceTarget::SurfaceHandle(_)
| SurfaceTarget::SwapChainPanel(_) => {}
}
Expand Down
1 change: 1 addition & 0 deletions wgpu-hal/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1752,6 +1752,7 @@ pub struct InstanceDescriptor<'a> {
pub name: &'a str,
pub flags: wgt::InstanceFlags,
pub dx12_shader_compiler: wgt::Dx12Compiler,
pub dx12_use_dcomp: bool,
pub gles_minor_version: wgt::Gles3MinorVersion,
}

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 @@ -243,6 +243,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 @@ -254,6 +256,7 @@ impl Dx12BackendOptions {
let compiler = Dx12Compiler::from_env().unwrap_or_default();
Self {
shader_compiler: compiler,
use_dcomp: false,
}
}

Expand All @@ -263,7 +266,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