Skip to content

Commit 00a655c

Browse files
committed
Move surface_configure out of Global
1 parent 8c3879e commit 00a655c

File tree

2 files changed

+276
-267
lines changed

2 files changed

+276
-267
lines changed

wgpu-core/src/device/global.rs

Lines changed: 6 additions & 267 deletions
Original file line numberDiff line numberDiff line change
@@ -1737,276 +1737,15 @@ impl Global {
17371737
device_id: DeviceId,
17381738
config: &wgt::SurfaceConfiguration<Vec<TextureFormat>>,
17391739
) -> Option<present::ConfigureSurfaceError> {
1740-
use present::ConfigureSurfaceError as E;
1741-
profiling::scope!("surface_configure");
1742-
1743-
fn validate_surface_configuration(
1744-
config: &mut hal::SurfaceConfiguration,
1745-
caps: &hal::SurfaceCapabilities,
1746-
max_texture_dimension_2d: u32,
1747-
) -> Result<(), E> {
1748-
let width = config.extent.width;
1749-
let height = config.extent.height;
1750-
1751-
if width > max_texture_dimension_2d || height > max_texture_dimension_2d {
1752-
return Err(E::TooLarge {
1753-
width,
1754-
height,
1755-
max_texture_dimension_2d,
1756-
});
1757-
}
1758-
1759-
if !caps.present_modes.contains(&config.present_mode) {
1760-
// Automatic present mode checks.
1761-
//
1762-
// The "Automatic" modes are never supported by the backends.
1763-
let fallbacks = match config.present_mode {
1764-
wgt::PresentMode::AutoVsync => {
1765-
&[wgt::PresentMode::FifoRelaxed, wgt::PresentMode::Fifo][..]
1766-
}
1767-
// Always end in FIFO to make sure it's always supported
1768-
wgt::PresentMode::AutoNoVsync => &[
1769-
wgt::PresentMode::Immediate,
1770-
wgt::PresentMode::Mailbox,
1771-
wgt::PresentMode::Fifo,
1772-
][..],
1773-
_ => {
1774-
return Err(E::UnsupportedPresentMode {
1775-
requested: config.present_mode,
1776-
available: caps.present_modes.clone(),
1777-
});
1778-
}
1779-
};
1780-
1781-
let new_mode = fallbacks
1782-
.iter()
1783-
.copied()
1784-
.find(|fallback| caps.present_modes.contains(fallback))
1785-
.unwrap_or_else(|| {
1786-
unreachable!(
1787-
"Fallback system failed to choose present mode. \
1788-
This is a bug. Mode: {:?}, Options: {:?}",
1789-
config.present_mode, &caps.present_modes
1790-
);
1791-
});
1792-
1793-
api_log!(
1794-
"Automatically choosing presentation mode by rule {:?}. Chose {new_mode:?}",
1795-
config.present_mode
1796-
);
1797-
config.present_mode = new_mode;
1798-
}
1799-
if !caps.formats.contains(&config.format) {
1800-
return Err(E::UnsupportedFormat {
1801-
requested: config.format,
1802-
available: caps.formats.clone(),
1803-
});
1804-
}
1805-
if !caps
1806-
.composite_alpha_modes
1807-
.contains(&config.composite_alpha_mode)
1808-
{
1809-
let new_alpha_mode = 'alpha: {
1810-
// Automatic alpha mode checks.
1811-
let fallbacks = match config.composite_alpha_mode {
1812-
wgt::CompositeAlphaMode::Auto => &[
1813-
wgt::CompositeAlphaMode::Opaque,
1814-
wgt::CompositeAlphaMode::Inherit,
1815-
][..],
1816-
_ => {
1817-
return Err(E::UnsupportedAlphaMode {
1818-
requested: config.composite_alpha_mode,
1819-
available: caps.composite_alpha_modes.clone(),
1820-
});
1821-
}
1822-
};
1823-
1824-
for &fallback in fallbacks {
1825-
if caps.composite_alpha_modes.contains(&fallback) {
1826-
break 'alpha fallback;
1827-
}
1828-
}
1829-
1830-
unreachable!(
1831-
"Fallback system failed to choose alpha mode. This is a bug. \
1832-
AlphaMode: {:?}, Options: {:?}",
1833-
config.composite_alpha_mode, &caps.composite_alpha_modes
1834-
);
1835-
};
1740+
let device = self.hub.devices.get(device_id);
1741+
let surface = self.surfaces.get(surface_id);
18361742

1837-
api_log!(
1838-
"Automatically choosing alpha mode by rule {:?}. Chose {new_alpha_mode:?}",
1839-
config.composite_alpha_mode
1840-
);
1841-
config.composite_alpha_mode = new_alpha_mode;
1842-
}
1843-
if !caps.usage.contains(config.usage) {
1844-
return Err(E::UnsupportedUsage {
1845-
requested: config.usage,
1846-
available: caps.usage,
1847-
});
1848-
}
1849-
if width == 0 || height == 0 {
1850-
return Err(E::ZeroArea);
1851-
}
1852-
Ok(())
1743+
#[cfg(feature = "trace")]
1744+
if let Some(ref mut trace) = *device.trace.lock() {
1745+
trace.add(trace::Action::ConfigureSurface(surface_id, config.clone()));
18531746
}
18541747

1855-
log::debug!("configuring surface with {config:?}");
1856-
1857-
let error = 'error: {
1858-
// User callbacks must not be called while we are holding locks.
1859-
let user_callbacks;
1860-
{
1861-
let device = self.hub.devices.get(device_id);
1862-
1863-
#[cfg(feature = "trace")]
1864-
if let Some(ref mut trace) = *device.trace.lock() {
1865-
trace.add(trace::Action::ConfigureSurface(surface_id, config.clone()));
1866-
}
1867-
1868-
if let Err(e) = device.check_is_valid() {
1869-
break 'error e.into();
1870-
}
1871-
1872-
let surface = self.surfaces.get(surface_id);
1873-
1874-
let caps = match surface.get_capabilities(&device.adapter) {
1875-
Ok(caps) => caps,
1876-
Err(_) => break 'error E::UnsupportedQueueFamily,
1877-
};
1878-
1879-
let mut hal_view_formats = Vec::new();
1880-
for format in config.view_formats.iter() {
1881-
if *format == config.format {
1882-
continue;
1883-
}
1884-
if !caps.formats.contains(&config.format) {
1885-
break 'error E::UnsupportedFormat {
1886-
requested: config.format,
1887-
available: caps.formats,
1888-
};
1889-
}
1890-
if config.format.remove_srgb_suffix() != format.remove_srgb_suffix() {
1891-
break 'error E::InvalidViewFormat(*format, config.format);
1892-
}
1893-
hal_view_formats.push(*format);
1894-
}
1895-
1896-
if !hal_view_formats.is_empty() {
1897-
if let Err(missing_flag) =
1898-
device.require_downlevel_flags(wgt::DownlevelFlags::SURFACE_VIEW_FORMATS)
1899-
{
1900-
break 'error E::MissingDownlevelFlags(missing_flag);
1901-
}
1902-
}
1903-
1904-
let maximum_frame_latency = config.desired_maximum_frame_latency.clamp(
1905-
*caps.maximum_frame_latency.start(),
1906-
*caps.maximum_frame_latency.end(),
1907-
);
1908-
let mut hal_config = hal::SurfaceConfiguration {
1909-
maximum_frame_latency,
1910-
present_mode: config.present_mode,
1911-
composite_alpha_mode: config.alpha_mode,
1912-
format: config.format,
1913-
extent: wgt::Extent3d {
1914-
width: config.width,
1915-
height: config.height,
1916-
depth_or_array_layers: 1,
1917-
},
1918-
usage: conv::map_texture_usage(
1919-
config.usage,
1920-
hal::FormatAspects::COLOR,
1921-
wgt::TextureFormatFeatureFlags::STORAGE_READ_ONLY
1922-
| wgt::TextureFormatFeatureFlags::STORAGE_WRITE_ONLY
1923-
| wgt::TextureFormatFeatureFlags::STORAGE_READ_WRITE,
1924-
),
1925-
view_formats: hal_view_formats,
1926-
};
1927-
1928-
if let Err(error) = validate_surface_configuration(
1929-
&mut hal_config,
1930-
&caps,
1931-
device.limits.max_texture_dimension_2d,
1932-
) {
1933-
break 'error error;
1934-
}
1935-
1936-
// Wait for all work to finish before configuring the surface.
1937-
let snatch_guard = device.snatchable_lock.read();
1938-
let fence = device.fence.read();
1939-
1940-
let maintain_result;
1941-
(user_callbacks, maintain_result) =
1942-
device.maintain(fence, wgt::PollType::wait_indefinitely(), snatch_guard);
1943-
1944-
match maintain_result {
1945-
// We're happy
1946-
Ok(wgt::PollStatus::QueueEmpty) => {}
1947-
Ok(wgt::PollStatus::WaitSucceeded) => {
1948-
// After the wait, the queue should be empty. It can only be non-empty
1949-
// if another thread is submitting at the same time.
1950-
break 'error E::GpuWaitTimeout;
1951-
}
1952-
Ok(wgt::PollStatus::Poll) => {
1953-
unreachable!("Cannot get a Poll result from a Wait action.")
1954-
}
1955-
Err(WaitIdleError::Timeout) if cfg!(target_arch = "wasm32") => {
1956-
// On wasm, you cannot actually successfully wait for the surface.
1957-
// However WebGL does not actually require you do this, so ignoring
1958-
// the failure is totally fine. See https://github.com/gfx-rs/wgpu/issues/7363
1959-
}
1960-
Err(e) => {
1961-
break 'error e.into();
1962-
}
1963-
}
1964-
1965-
// All textures must be destroyed before the surface can be re-configured.
1966-
if let Some(present) = surface.presentation.lock().take() {
1967-
if present.acquired_texture.is_some() {
1968-
break 'error E::PreviousOutputExists;
1969-
}
1970-
}
1971-
1972-
// TODO: Texture views may still be alive that point to the texture.
1973-
// this will allow the user to render to the surface texture, long after
1974-
// it has been removed.
1975-
//
1976-
// https://github.com/gfx-rs/wgpu/issues/4105
1977-
1978-
let surface_raw = surface.raw(device.backend()).unwrap();
1979-
match unsafe { surface_raw.configure(device.raw(), &hal_config) } {
1980-
Ok(()) => (),
1981-
Err(error) => {
1982-
break 'error match error {
1983-
hal::SurfaceError::Outdated | hal::SurfaceError::Lost => {
1984-
E::InvalidSurface
1985-
}
1986-
hal::SurfaceError::Device(error) => {
1987-
E::Device(device.handle_hal_error(error))
1988-
}
1989-
hal::SurfaceError::Other(message) => {
1990-
log::error!("surface configuration failed: {message}");
1991-
E::InvalidSurface
1992-
}
1993-
}
1994-
}
1995-
}
1996-
1997-
let mut presentation = surface.presentation.lock();
1998-
*presentation = Some(present::Presentation {
1999-
device,
2000-
config: config.clone(),
2001-
acquired_texture: None,
2002-
});
2003-
}
2004-
2005-
user_callbacks.fire();
2006-
return None;
2007-
};
2008-
2009-
Some(error)
1748+
device.configure_surface(&surface, config)
20101749
}
20111750

20121751
/// Check `device_id` for freeable resources and completed buffer mappings.

0 commit comments

Comments
 (0)