Skip to content
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

Improve Presentation Api #2803

Merged
merged 7 commits into from
Jun 30, 2022
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
2 changes: 1 addition & 1 deletion cts_runner/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ version = "0.1.0"
authors = [
"Luca Casonato <hello@lcas.dev>",
]
edition = "2018"
edition = "2021"
description = "CTS runner for wgpu"
license = "MIT OR Apache-2.0"
publish = false
Expand Down
2 changes: 1 addition & 1 deletion deno_webgpu/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
name = "deno_webgpu"
version = "0.54.0"
authors = ["the Deno authors"]
edition = "2018"
edition = "2021"
license = "MIT"
readme = "README.md"
repository = "https://github.com/gfx-rs/wgpu"
Expand Down
2 changes: 1 addition & 1 deletion dummy/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ version = "0.1.0"
authors = [
"Dzmitry Malyshau <kvark@mozilla.com>",
]
edition = "2018"
edition = "2021"
license = "MIT OR Apache-2.0"
publish = false

Expand Down
2 changes: 1 addition & 1 deletion player/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ version = "0.1.0"
authors = [
"Dzmitry Malyshau <kvark@mozilla.com>",
]
edition = "2018"
edition = "2021"
description = "WebGPU trace player"
homepage = "https://github.com/gfx-rs/wgpu"
repository = "https://github.com/gfx-rs/wgpu"
Expand Down
2 changes: 1 addition & 1 deletion run-wasm/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[package]
name = "run-wasm"
version = "0.1.0"
edition = "2018"
edition = "2021"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

Expand Down
2 changes: 1 addition & 1 deletion wgpu-core/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
name = "wgpu-core"
version = "0.12.0"
authors = ["wgpu developers"]
edition = "2018"
edition = "2021"
description = "WebGPU core logic on wgpu-hal"
homepage = "https://github.com/gfx-rs/wgpu"
repository = "https://github.com/gfx-rs/wgpu"
Expand Down
63 changes: 56 additions & 7 deletions wgpu-core/src/device/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3117,7 +3117,7 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
&self,
surface_id: id::SurfaceId,
adapter_id: id::AdapterId,
) -> Result<Vec<TextureFormat>, instance::GetSurfacePreferredFormatError> {
) -> Result<Vec<TextureFormat>, instance::GetSurfaceSupportError> {
profiling::scope!("Surface::get_supported_formats");
let hub = A::hub(self);
let mut token = Token::root();
Expand All @@ -3126,13 +3126,33 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
let (adapter_guard, mut _token) = hub.adapters.read(&mut token);
let adapter = adapter_guard
.get(adapter_id)
.map_err(|_| instance::GetSurfacePreferredFormatError::InvalidAdapter)?;
.map_err(|_| instance::GetSurfaceSupportError::InvalidAdapter)?;
let surface = surface_guard
.get(surface_id)
.map_err(|_| instance::GetSurfacePreferredFormatError::InvalidSurface)?;
.map_err(|_| instance::GetSurfaceSupportError::InvalidSurface)?;

surface.get_supported_formats(adapter)
}
pub fn surface_get_supported_modes<A: HalApi>(
&self,
surface_id: id::SurfaceId,
adapter_id: id::AdapterId,
) -> Result<Vec<wgt::PresentMode>, instance::GetSurfaceSupportError> {
profiling::scope!("Surface::get_supported_modes");
let hub = A::hub(self);
let mut token = Token::root();

let (surface_guard, mut token) = self.surfaces.read(&mut token);
let (adapter_guard, mut _token) = hub.adapters.read(&mut token);
let adapter = adapter_guard
.get(adapter_id)
.map_err(|_| instance::GetSurfaceSupportError::InvalidAdapter)?;
let surface = surface_guard
.get(surface_id)
.map_err(|_| instance::GetSurfaceSupportError::InvalidSurface)?;

surface.get_supported_modes(adapter)
}

pub fn device_features<A: HalApi>(
&self,
Expand Down Expand Up @@ -4938,11 +4958,40 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
);
}
if !caps.present_modes.contains(&config.present_mode) {
log::warn!(
"Surface does not support present mode: {:?}, falling back to FIFO",
config.present_mode,
let new_mode = loop {
// Automatic present mode checks.
//
// The "Automatic" modes are never supported by the backends.
match config.present_mode {
wgt::PresentMode::AutoVsync => {
if caps.present_modes.contains(&wgt::PresentMode::FifoRelaxed) {
break wgt::PresentMode::FifoRelaxed;
}
if caps.present_modes.contains(&wgt::PresentMode::Fifo) {
break wgt::PresentMode::Fifo;
}
}
wgt::PresentMode::AutoNoVsync => {
if caps.present_modes.contains(&wgt::PresentMode::Immediate) {
break wgt::PresentMode::Immediate;
}
if caps.present_modes.contains(&wgt::PresentMode::Mailbox) {
break wgt::PresentMode::Mailbox;
}
}
_ => {}
}
return Err(E::UnsupportedPresentMode {
requested: config.present_mode,
available: caps.present_modes.clone(),
});
};

log::info!(
"Automatically choosing presentation mode by rule {:?}. Chose {new_mode:?}",
config.present_mode
);
config.present_mode = wgt::PresentMode::Fifo;
config.present_mode = new_mode;
}
if !caps.formats.contains(&config.format) {
return Err(E::UnsupportedFormat {
Expand Down
23 changes: 20 additions & 3 deletions wgpu-core/src/instance.rs
Original file line number Diff line number Diff line change
Expand Up @@ -155,22 +155,39 @@ impl Surface {
pub fn get_supported_formats<A: HalApi>(
&self,
adapter: &Adapter<A>,
) -> Result<Vec<wgt::TextureFormat>, GetSurfacePreferredFormatError> {
) -> Result<Vec<wgt::TextureFormat>, GetSurfaceSupportError> {
let suf = A::get_surface(self);
let mut caps = unsafe {
profiling::scope!("surface_capabilities");
adapter
.raw
.adapter
.surface_capabilities(&suf.raw)
.ok_or(GetSurfacePreferredFormatError::UnsupportedQueueFamily)?
.ok_or(GetSurfaceSupportError::UnsupportedQueueFamily)?
};

// TODO: maybe remove once we support texture view changing srgb-ness
caps.formats.sort_by_key(|f| !f.describe().srgb);

Ok(caps.formats)
}

pub fn get_supported_modes<A: HalApi>(
&self,
adapter: &Adapter<A>,
) -> Result<Vec<wgt::PresentMode>, GetSurfaceSupportError> {
let suf = A::get_surface(self);
let caps = unsafe {
profiling::scope!("surface_capabilities");
adapter
.raw
.adapter
.surface_capabilities(&suf.raw)
.ok_or(GetSurfaceSupportError::UnsupportedQueueFamily)?
};

Ok(caps.present_modes)
}
}

pub struct Adapter<A: hal::Api> {
Expand Down Expand Up @@ -341,7 +358,7 @@ pub enum IsSurfaceSupportedError {
}

#[derive(Clone, Debug, Error)]
pub enum GetSurfacePreferredFormatError {
pub enum GetSurfaceSupportError {
#[error("invalid adapter")]
InvalidAdapter,
#[error("invalid surface")]
Expand Down
5 changes: 5 additions & 0 deletions wgpu-core/src/present.rs
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,11 @@ pub enum ConfigureSurfaceError {
requested: wgt::TextureFormat,
available: Vec<wgt::TextureFormat>,
},
#[error("requested present mode {requested:?} is not in the list of supported present modes: {available:?}")]
UnsupportedPresentMode {
requested: wgt::PresentMode,
available: Vec<wgt::PresentMode>,
},
#[error("requested usage is not supported")]
UnsupportedUsage,
}
Expand Down
2 changes: 1 addition & 1 deletion wgpu-hal/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
name = "wgpu-hal"
version = "0.12.0"
authors = ["wgpu developers"]
edition = "2018"
edition = "2021"
description = "WebGPU hardware abstraction layer"
homepage = "https://github.com/gfx-rs/wgpu"
repository = "https://github.com/gfx-rs/wgpu"
Expand Down
19 changes: 4 additions & 15 deletions wgpu-hal/src/dx12/adapter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use crate::{
};
use std::{mem, sync::Arc, thread};
use winapi::{
shared::{dxgi, dxgi1_2, dxgi1_5, minwindef, windef, winerror},
shared::{dxgi, dxgi1_2, windef, winerror},
um::{d3d12, d3d12sdklayers, winuser},
};

Expand Down Expand Up @@ -425,20 +425,9 @@ impl crate::Adapter<super::Api> for super::Adapter {
}
};

let mut present_modes = vec![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),
}
let mut present_modes = vec![wgt::PresentMode::Mailbox, wgt::PresentMode::Fifo];
if surface.supports_allow_tearing {
present_modes.push(wgt::PresentMode::Immediate);
}

Some(crate::SurfaceCapabilities {
Expand Down
22 changes: 21 additions & 1 deletion wgpu-hal/src/dx12/instance.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
use winapi::shared::{dxgi1_5, minwindef};

use super::SurfaceTarget;
use crate::auxil::{self, dxgi::result::HResult as _};
use std::sync::Arc;
use std::{mem, sync::Arc};

impl Drop for super::Instance {
fn drop(&mut self) {
Expand Down Expand Up @@ -37,11 +39,28 @@ impl crate::Instance<super::Api> for super::Instance {
desc.flags,
)?;

let mut supports_allow_tearing = false;
#[allow(trivial_casts)]
if let Some(factory5) = 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,
}
}

Ok(Self {
// The call to create_factory will only succeed if we get a factory4, so this is safe.
factory,
library: Arc::new(lib_main),
_lib_dxgi: lib_dxgi,
supports_allow_tearing,
flags: desc.flags,
})
}
Expand All @@ -54,6 +73,7 @@ impl crate::Instance<super::Api> for super::Instance {
raw_window_handle::RawWindowHandle::Win32(handle) => Ok(super::Surface {
factory: self.factory,
target: SurfaceTarget::WndHandle(handle.hwnd as *mut _),
supports_allow_tearing: self.supports_allow_tearing,
swap_chain: None,
}),
_ => Err(crate::InstanceError),
Expand Down
17 changes: 11 additions & 6 deletions wgpu-hal/src/dx12/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ const ZERO_BUFFER_SIZE: wgt::BufferAddress = 256 << 10;
pub struct Instance {
factory: native::DxgiFactory,
library: Arc<native::D3D12Lib>,
supports_allow_tearing: bool,
_lib_dxgi: native::DxgiLib,
flags: crate::InstanceFlags,
}
Expand All @@ -100,6 +101,7 @@ impl Instance {
Surface {
factory: self.factory,
target: SurfaceTarget::Visual(native::WeakPtr::from_raw(visual)),
supports_allow_tearing: self.supports_allow_tearing,
swap_chain: None,
}
}
Expand Down Expand Up @@ -128,6 +130,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 +557,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,9 +772,11 @@ 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),
wgt::PresentMode::Mailbox => (1, 0),
m => unreachable!("Cannot make surface with present mode {m:?}"),
};

profiling::scope!("IDXGISwapchain3::Present");
Expand Down
16 changes: 11 additions & 5 deletions wgpu-hal/src/metal/adapter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -281,13 +281,18 @@ impl crate::Adapter<super::Api> for super::Adapter {
None
};

let mut formats = vec![
wgt::TextureFormat::Bgra8Unorm,
wgt::TextureFormat::Bgra8UnormSrgb,
wgt::TextureFormat::Rgba16Float,
];
if self.shared.private_caps.format_rgb10a2_unorm_surface {
formats.push(wgt::TextureFormat::Rgb10a2Unorm);
}

let pc = &self.shared.private_caps;
Some(crate::SurfaceCapabilities {
formats: vec![
wgt::TextureFormat::Bgra8Unorm,
wgt::TextureFormat::Bgra8UnormSrgb,
wgt::TextureFormat::Rgba16Float,
],
formats,
//Note: this is hardcoded in `CAMetalLayer` documentation
swap_chain_sizes: if pc.can_set_maximum_drawables_count {
2..=3
Expand Down Expand Up @@ -575,6 +580,7 @@ impl super::PrivateCapabilities {
format_rgba8_srgb_no_write: !Self::supports_any(device, RGBA8_SRGB),
format_rgb10a2_unorm_all: Self::supports_any(device, RGB10A2UNORM_ALL),
format_rgb10a2_unorm_no_write: !Self::supports_any(device, RGB10A2UNORM_ALL),
format_rgb10a2_unorm_surface: os_is_mac,
format_rgb10a2_uint_color: !Self::supports_any(device, RGB10A2UINT_COLOR_WRITE),
format_rgb10a2_uint_color_write: Self::supports_any(device, RGB10A2UINT_COLOR_WRITE),
format_rg11b10_all: Self::supports_any(device, RG11B10FLOAT_ALL),
Expand Down
1 change: 1 addition & 0 deletions wgpu-hal/src/metal/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,7 @@ struct PrivateCapabilities {
format_rgba8_srgb_no_write: bool,
format_rgb10a2_unorm_all: bool,
format_rgb10a2_unorm_no_write: bool,
format_rgb10a2_unorm_surface: bool,
format_rgb10a2_uint_color: bool,
format_rgb10a2_uint_color_write: bool,
format_rg11b10_all: bool,
Expand Down
Loading