-
Notifications
You must be signed in to change notification settings - Fork 1k
Allow disabling waiting for latency waitable object #7400
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: trunk
Are you sure you want to change the base?
Changes from all commits
a5ab3ac
075f5eb
948b407
c293205
84d4b27
a15f887
a4e4d03
0e74572
4e1b813
2298c4d
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -459,6 +459,7 @@ pub struct Instance { | |
supports_allow_tearing: bool, | ||
_lib_dxgi: DxgiLib, | ||
flags: wgt::InstanceFlags, | ||
options: wgt::Dx12BackendOptions, | ||
dxc_container: Option<Arc<shader_compilation::DxcContainer>>, | ||
} | ||
|
||
|
@@ -472,6 +473,7 @@ impl Instance { | |
target: SurfaceTarget::Visual(visual.to_owned()), | ||
supports_allow_tearing: self.supports_allow_tearing, | ||
swap_chain: RwLock::new(None), | ||
options: self.options.clone(), | ||
} | ||
} | ||
|
||
|
@@ -489,6 +491,7 @@ impl Instance { | |
target: SurfaceTarget::SurfaceHandle(surface_handle), | ||
supports_allow_tearing: self.supports_allow_tearing, | ||
swap_chain: RwLock::new(None), | ||
options: self.options.clone(), | ||
} | ||
} | ||
|
||
|
@@ -505,6 +508,7 @@ impl Instance { | |
target: SurfaceTarget::SwapChainPanel(swap_chain_panel.to_owned()), | ||
supports_allow_tearing: self.supports_allow_tearing, | ||
swap_chain: RwLock::new(None), | ||
options: self.options.clone(), | ||
} | ||
} | ||
} | ||
|
@@ -519,7 +523,7 @@ struct SwapChain { | |
// when the swapchain is destroyed | ||
resources: Vec<Direct3D12::ID3D12Resource>, | ||
/// Handle is freed in [`Self::release_resources()`] | ||
waitable: Foundation::HANDLE, | ||
waitable: Option<Foundation::HANDLE>, | ||
acquired_count: usize, | ||
present_mode: wgt::PresentMode, | ||
format: wgt::TextureFormat, | ||
|
@@ -541,11 +545,23 @@ pub struct Surface { | |
target: SurfaceTarget, | ||
supports_allow_tearing: bool, | ||
swap_chain: RwLock<Option<SwapChain>>, | ||
options: wgt::Dx12BackendOptions, | ||
} | ||
|
||
unsafe impl Send for Surface {} | ||
unsafe impl Sync for Surface {} | ||
|
||
impl Surface { | ||
/// Returns the waitable handle of the swapchain, if it exists. | ||
pub unsafe fn waitable_handle(&self) -> Option<Foundation::HANDLE> { | ||
let swapchain = self.swap_chain.read(); | ||
if let Some(swap_chain) = swapchain.as_ref() { | ||
return swap_chain.waitable.clone(); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This implies that Handles are refcounted, but they are Copy aliases around There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. so just drop the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yeah |
||
} | ||
None | ||
} | ||
} | ||
|
||
#[derive(Debug, Clone, Copy)] | ||
enum MemoryArchitecture { | ||
Unified { | ||
|
@@ -585,6 +601,7 @@ pub struct Adapter { | |
#[allow(unused)] | ||
workarounds: Workarounds, | ||
dxc_container: Option<Arc<shader_compilation::DxcContainer>>, | ||
options: wgt::Dx12BackendOptions, | ||
} | ||
|
||
unsafe impl Send for Adapter {} | ||
|
@@ -636,6 +653,7 @@ pub struct Device { | |
private_caps: PrivateCapabilities, | ||
features: wgt::Features, | ||
shared: Arc<DeviceShared>, | ||
options: wgt::Dx12BackendOptions, | ||
// CPU only pools | ||
rtv_pool: Mutex<descriptor::CpuPool>, | ||
dsv_pool: Mutex<descriptor::CpuPool>, | ||
|
@@ -1118,7 +1136,9 @@ impl crate::DynAccelerationStructure for AccelerationStructure {} | |
|
||
impl SwapChain { | ||
unsafe fn release_resources(mut self) -> Dxgi::IDXGISwapChain3 { | ||
unsafe { Foundation::HANDLE::free(&mut self.waitable) }; | ||
if let Some(mut waitable) = self.waitable.take() { | ||
unsafe { Foundation::HANDLE::free(&mut waitable) }; | ||
} | ||
self.raw | ||
} | ||
|
||
|
@@ -1130,14 +1150,21 @@ impl SwapChain { | |
Some(duration) => duration.as_millis() as u32, | ||
None => Threading::INFINITE, | ||
}; | ||
match unsafe { Threading::WaitForSingleObject(self.waitable, timeout_ms) } { | ||
Foundation::WAIT_ABANDONED | Foundation::WAIT_FAILED => Err(crate::SurfaceError::Lost), | ||
Foundation::WAIT_OBJECT_0 => Ok(true), | ||
Foundation::WAIT_TIMEOUT => Ok(false), | ||
other => { | ||
log::error!("Unexpected wait status: 0x{:x?}", other); | ||
Err(crate::SurfaceError::Lost) | ||
|
||
if let Some(waitable) = self.waitable { | ||
match unsafe { Threading::WaitForSingleObject(waitable, timeout_ms) } { | ||
Foundation::WAIT_ABANDONED | Foundation::WAIT_FAILED => { | ||
Err(crate::SurfaceError::Lost) | ||
} | ||
Foundation::WAIT_OBJECT_0 => Ok(true), | ||
Foundation::WAIT_TIMEOUT => Ok(false), | ||
other => { | ||
log::error!("Unexpected wait status: 0x{:x?}", other); | ||
Err(crate::SurfaceError::Lost) | ||
} | ||
} | ||
} else { | ||
Ok(true) | ||
} | ||
} | ||
} | ||
|
@@ -1305,7 +1332,14 @@ impl crate::Surface for Surface { | |
|
||
unsafe { swap_chain.SetMaximumFrameLatency(config.maximum_frame_latency) } | ||
.into_device_result("SetMaximumFrameLatency")?; | ||
let waitable = unsafe { swap_chain.GetFrameLatencyWaitableObject() }; | ||
|
||
let waitable = match device.options.latency_waitable_object { | ||
wgt::Dx12UseFrameLatencyWaitableObject::None => None, | ||
wgt::Dx12UseFrameLatencyWaitableObject::Wait | ||
| wgt::Dx12UseFrameLatencyWaitableObject::DontWait => { | ||
Some(unsafe { swap_chain.GetFrameLatencyWaitableObject() }) | ||
} | ||
}; | ||
|
||
let mut resources = Vec::with_capacity(swap_chain_buffer as usize); | ||
for i in 0..swap_chain_buffer { | ||
|
@@ -1352,7 +1386,13 @@ impl crate::Surface for Surface { | |
let mut swapchain = self.swap_chain.write(); | ||
let sc = swapchain.as_mut().unwrap(); | ||
|
||
unsafe { sc.wait(timeout) }?; | ||
match self.options.latency_waitable_object { | ||
wgt::Dx12UseFrameLatencyWaitableObject::None | ||
| wgt::Dx12UseFrameLatencyWaitableObject::DontWait => {} | ||
wgt::Dx12UseFrameLatencyWaitableObject::Wait => { | ||
unsafe { sc.wait(timeout) }?; | ||
} | ||
} | ||
|
||
let base_index = unsafe { sc.raw.GetCurrentBackBufferIndex() } as usize; | ||
let index = (base_index + sc.acquired_count) % sc.resources.len(); | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should also define the lifetime of the handle
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Define the lifetime in a SAFETEY comment or as an actual Rust lifetime?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just as a safety comment, saying it's valid until the surface is reconfigured or unconfigured or whatever