Skip to content

Commit

Permalink
Fix issues with ALLOW_TEARING
Browse files Browse the repository at this point in the history
  • Loading branch information
cwfitzgerald committed Jun 25, 2022
1 parent f49e4e3 commit ec54fae
Show file tree
Hide file tree
Showing 3 changed files with 26 additions and 18 deletions.
15 changes: 2 additions & 13 deletions wgpu-hal/src/dx12/adapter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -426,19 +426,8 @@ impl crate::Adapter<super::Api> for super::Adapter {
};

let mut present_modes = vec![wgt::PresentMode::Mailbox, wgt::PresentMode::Fifo];
#[allow(trivial_casts)]
if let Some(factory5) = surface.factory.as_factory5() {
let mut allow_tearing: minwindef::BOOL = minwindef::FALSE;
let hr = factory5.CheckFeatureSupport(
dxgi1_5::DXGI_FEATURE_PRESENT_ALLOW_TEARING,
&mut allow_tearing as *mut _ as *mut _,
mem::size_of::<minwindef::BOOL>() as _,
);

match hr.into_result() {
Err(err) => log::warn!("Unable to check for tearing support: {}", err),
Ok(()) => present_modes.push(wgt::PresentMode::Immediate),
}
if surface.supports_allow_tearing {
present_mode.push(wgt::PresentMode::Immediate);
}

Some(crate::SurfaceCapabilities {
Expand Down
17 changes: 17 additions & 0 deletions wgpu-hal/src/dx12/instance.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,10 +50,27 @@ impl crate::Instance<super::Api> for super::Instance {
&self,
has_handle: &impl raw_window_handle::HasRawWindowHandle,
) -> Result<super::Surface, crate::InstanceError> {
let mut supports_allow_tearing = false;
#[allow(trivial_casts)]
if let Some(factory5) = self.factory.as_factory5() {
let mut allow_tearing: minwindef::BOOL = minwindef::FALSE;
let hr = factory5.CheckFeatureSupport(
dxgi1_5::DXGI_FEATURE_PRESENT_ALLOW_TEARING,
&mut allow_tearing as *mut _ as *mut _,
mem::size_of::<minwindef::BOOL>() as _,
);

match hr.into_result() {
Err(err) => log::warn!("Unable to check for tearing support: {}", err),
Ok(()) => supports_allow_tearing = true,
}
}

match has_handle.raw_window_handle() {
raw_window_handle::RawWindowHandle::Win32(handle) => Ok(super::Surface {
factory: self.factory,
target: SurfaceTarget::WndHandle(handle.hwnd as *mut _),
supports_allow_tearing,
swap_chain: None,
}),
_ => Err(crate::InstanceError),
Expand Down
12 changes: 7 additions & 5 deletions wgpu-hal/src/dx12/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,7 @@ enum SurfaceTarget {
pub struct Surface {
factory: native::DxgiFactory,
target: SurfaceTarget,
supports_allow_tearing: bool,
swap_chain: Option<SwapChain>,
}

Expand Down Expand Up @@ -554,11 +555,11 @@ impl crate::Surface<Api> for Surface {
config: &crate::SurfaceConfiguration,
) -> Result<(), crate::SurfaceError> {
let mut flags = dxgi::DXGI_SWAP_CHAIN_FLAG_FRAME_LATENCY_WAITABLE_OBJECT;
match config.present_mode {
wgt::PresentMode::Immediate => {
flags |= dxgi::DXGI_SWAP_CHAIN_FLAG_ALLOW_TEARING;
}
_ => {}
// We always set ALLOW_TEARING on the swapchain no matter
// what kind of swapchain we want because ResizeBuffers
// cannot change if ALLOW_TEARING is applied to the swapchain.
if self.supports_allow_tearing {
flags |= dxgi::DXGI_SWAP_CHAIN_FLAG_ALLOW_TEARING;
}

let non_srgb_format = auxil::dxgi::conv::map_texture_format_nosrgb(config.format);
Expand Down Expand Up @@ -769,6 +770,7 @@ impl crate::Queue<Api> for Queue {
sc.acquired_count -= 1;

let (interval, flags) = match sc.present_mode {
// We only allow immediate if ALLOW_TEARING is valid.
wgt::PresentMode::Immediate => (0, dxgi::DXGI_PRESENT_ALLOW_TEARING),
wgt::PresentMode::Mailbox => (0, 0),
wgt::PresentMode::Fifo => (1, 0),
Expand Down

0 comments on commit ec54fae

Please sign in to comment.