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

Cleanup Surface API #3236

Merged
merged 2 commits into from
Nov 27, 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
25 changes: 25 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,29 @@ Bottom level categories:

## Unreleased

### Major Changes

#### Surface Capabilities API

The various surface capability functions were combined into a single call that gives you all the capabilities.

```diff
- let formats = surface.get_supported_formats(&adapter);
- let present_modes = surface.get_supported_present_modes(&adapter);
- let alpha_modes = surface.get_supported_alpha_modes(&adapter);
+ let caps = surface.get_capabilities(&adapter);
+ let formats = caps.formats;
+ let present_modes = caps.present_modes;
+ let alpha_modes = caps.alpha_modes;
```

Additionally `Surface::get_default_config` now returns an Option and returns None if the surface isn't supported by the adapter.

```diff
- let config = surface.get_default_config(&adapter);
+ let config = surface.get_default_config(&adapter).expect("Surface unsupported by adapter");
```

### Changes

#### General
Expand All @@ -48,6 +71,8 @@ Bottom level categories:
- Implement `Default` for `CompositeAlphaMode`
- Improve compute shader validation error message. By @haraldreingruber in [#3139](https://github.com/gfx-rs/wgpu/pull/3139)
- New downlevel feature `UNRESTRICTED_INDEX_BUFFER` to indicate support for using `INDEX` together with other non-copy/map usages (unsupported on WebGL). By @Wumpf in [#3157](https://github.com/gfx-rs/wgpu/pull/3157)
- Combine `Surface::get_supported_formats`, `Surface::get_supported_present_modes`, and `Surface::get_supported_alpha_modes` into `Surface::get_capabilities` and `SurfaceCapabilities`. By @cwfitzgerald in [#3157](https://github.com/gfx-rs/wgpu/pull/3157)
- Make `Surface::get_default_config` return an Option to prevent panics. By @cwfitzgerald in [#3157](https://github.com/gfx-rs/wgpu/pull/3157)

#### WebGPU

Expand Down
46 changes: 12 additions & 34 deletions wgpu-core/src/device/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3214,43 +3214,21 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
Ok(adapter.is_surface_supported(surface))
}

pub fn surface_get_supported_formats<A: HalApi>(
pub fn surface_get_capabilities<A: HalApi>(
&self,
surface_id: id::SurfaceId,
adapter_id: id::AdapterId,
) -> Result<Vec<TextureFormat>, instance::GetSurfaceSupportError> {
profiling::scope!("Surface::get_supported_formats");
self.fetch_adapter_and_surface::<A, _, Vec<TextureFormat>>(
surface_id,
adapter_id,
|adapter, surface| surface.get_supported_formats(adapter),
)
}

pub fn surface_get_supported_present_modes<A: HalApi>(
&self,
surface_id: id::SurfaceId,
adapter_id: id::AdapterId,
) -> Result<Vec<wgt::PresentMode>, instance::GetSurfaceSupportError> {
profiling::scope!("Surface::get_supported_present_modes");
self.fetch_adapter_and_surface::<A, _, Vec<wgt::PresentMode>>(
surface_id,
adapter_id,
|adapter, surface| surface.get_supported_present_modes(adapter),
)
}

pub fn surface_get_supported_alpha_modes<A: HalApi>(
&self,
surface_id: id::SurfaceId,
adapter_id: id::AdapterId,
) -> Result<Vec<wgt::CompositeAlphaMode>, instance::GetSurfaceSupportError> {
profiling::scope!("Surface::get_supported_alpha_modes");
self.fetch_adapter_and_surface::<A, _, Vec<wgt::CompositeAlphaMode>>(
surface_id,
adapter_id,
|adapter, surface| surface.get_supported_alpha_modes(adapter),
)
) -> Result<wgt::SurfaceCapabilities, instance::GetSurfaceSupportError> {
profiling::scope!("Surface::get_capabilities");
self.fetch_adapter_and_surface::<A, _, _>(surface_id, adapter_id, |adapter, surface| {
let hal_caps = surface.get_capabilities(adapter)?;

Ok(wgt::SurfaceCapabilities {
formats: hal_caps.formats,
present_modes: hal_caps.present_modes,
alpha_modes: hal_caps.composite_alpha_modes,
})
})
}

fn fetch_adapter_and_surface<
Expand Down
33 changes: 3 additions & 30 deletions wgpu-core/src/instance.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use crate::{

use wgt::{Backend, Backends, PowerPreference};

use hal::{Adapter as _, Instance as _, SurfaceCapabilities};
use hal::{Adapter as _, Instance as _};
use thiserror::Error;

pub type RequestAdapterOptions = wgt::RequestAdapterOptions<SurfaceId>;
Expand Down Expand Up @@ -152,37 +152,10 @@ impl crate::hub::Resource for Surface {
}

impl Surface {
pub fn get_supported_formats<A: HalApi>(
pub fn get_capabilities<A: HalApi>(
&self,
adapter: &Adapter<A>,
) -> Result<Vec<wgt::TextureFormat>, GetSurfaceSupportError> {
self.get_capabilities(adapter).map(|mut caps| {
// TODO: maybe remove once we support texture view changing srgb-ness
caps.formats.sort_by_key(|f| !f.describe().srgb);
caps.formats
})
}

pub fn get_supported_present_modes<A: HalApi>(
&self,
adapter: &Adapter<A>,
) -> Result<Vec<wgt::PresentMode>, GetSurfaceSupportError> {
self.get_capabilities(adapter)
.map(|caps| caps.present_modes)
}

pub fn get_supported_alpha_modes<A: HalApi>(
&self,
adapter: &Adapter<A>,
) -> Result<Vec<wgt::CompositeAlphaMode>, GetSurfaceSupportError> {
self.get_capabilities(adapter)
.map(|caps| caps.composite_alpha_modes)
}

fn get_capabilities<A: HalApi>(
&self,
adapter: &Adapter<A>,
) -> Result<SurfaceCapabilities, GetSurfaceSupportError> {
) -> Result<hal::SurfaceCapabilities, GetSurfaceSupportError> {
let suf = A::get_surface(self).ok_or(GetSurfaceSupportError::Unsupported)?;
profiling::scope!("surface_capabilities");
let caps = unsafe {
Expand Down
27 changes: 27 additions & 0 deletions wgpu-types/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3849,6 +3849,33 @@ bitflags::bitflags! {
#[cfg(feature = "bitflags_serde_shim")]
bitflags_serde_shim::impl_serde_for_bitflags!(TextureUsages);

/// Defines the capabilities of a given surface and adapter.
#[derive(Debug)]
pub struct SurfaceCapabilities {
/// List of supported formats to use with the given adapter. The first format in the vector is preferred.
///
/// Returns an empty vector if the surface is incompatible with the adapter.
pub formats: Vec<TextureFormat>,
/// List of supported presentation modes to use with the given adapter.
///
/// Returns an empty vector if the surface is incompatible with the adapter.
pub present_modes: Vec<PresentMode>,
/// List of supported alpha modes to use with the given adapter.
///
/// Will return at least one element, CompositeAlphaMode::Opaque or CompositeAlphaMode::Inherit.
pub alpha_modes: Vec<CompositeAlphaMode>,
}

impl Default for SurfaceCapabilities {
fn default() -> Self {
Self {
formats: Vec::new(),
present_modes: Vec::new(),
alpha_modes: vec![CompositeAlphaMode::Opaque],
}
}
}

/// Configures a [`Surface`] for presentation.
///
/// [`Surface`]: ../wgpu/struct.Surface.html
Expand Down
4 changes: 3 additions & 1 deletion wgpu/examples/framework.rs
Original file line number Diff line number Diff line change
Expand Up @@ -267,7 +267,9 @@ fn start<E: Example>(
}: Setup,
) {
let spawner = Spawner::new();
let mut config = surface.get_default_config(&adapter, size.width, size.height);
let mut config = surface
.get_default_config(&adapter, size.width, size.height)
.expect("Surface isn't supported by the adapter.");
surface.configure(&device, &config);

log::info!("Initializing the example...");
Expand Down
5 changes: 3 additions & 2 deletions wgpu/examples/hello-triangle/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,8 @@ async fn run(event_loop: EventLoop<()>, window: Window) {
push_constant_ranges: &[],
});

let swapchain_format = surface.get_supported_formats(&adapter)[0];
let swapchain_capabilities = surface.get_capabilities(&adapter);
let swapchain_format = swapchain_capabilities.formats[0];

let render_pipeline = device.create_render_pipeline(&wgpu::RenderPipelineDescriptor {
label: None,
Expand All @@ -73,7 +74,7 @@ async fn run(event_loop: EventLoop<()>, window: Window) {
width: size.width,
height: size.height,
present_mode: wgpu::PresentMode::Fifo,
alpha_mode: surface.get_supported_alpha_modes(&adapter)[0],
alpha_mode: swapchain_capabilities.alpha_modes[0],
};

surface.configure(&device, &config);
Expand Down
5 changes: 3 additions & 2 deletions wgpu/examples/hello-windows/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,13 +31,14 @@ impl ViewportDesc {
fn build(self, adapter: &wgpu::Adapter, device: &wgpu::Device) -> Viewport {
let size = self.window.inner_size();

let caps = self.surface.get_capabilities(adapter);
let config = wgpu::SurfaceConfiguration {
usage: wgpu::TextureUsages::RENDER_ATTACHMENT,
format: self.surface.get_supported_formats(adapter)[0],
format: caps.formats[0],
width: size.width,
height: size.height,
present_mode: wgpu::PresentMode::Fifo,
alpha_mode: self.surface.get_supported_alpha_modes(adapter)[0],
alpha_mode: caps.alpha_modes[0],
};

self.surface.configure(device, &config);
Expand Down
44 changes: 7 additions & 37 deletions wgpu/src/backend/direct.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use crate::{
DownlevelCapabilities, Features, Label, Limits, LoadOp, MapMode, Operations,
PipelineLayoutDescriptor, RenderBundleEncoderDescriptor, RenderPipelineDescriptor,
SamplerDescriptor, ShaderModuleDescriptor, ShaderModuleDescriptorSpirV, ShaderSource,
SurfaceStatus, TextureDescriptor, TextureFormat, TextureViewDescriptor,
SurfaceStatus, TextureDescriptor, TextureViewDescriptor,
};

use arrayvec::ArrayVec;
Expand All @@ -19,7 +19,6 @@ use std::{
slice,
sync::Arc,
};
use wgt::{CompositeAlphaMode, PresentMode};

const LABEL: &str = "label";

Expand Down Expand Up @@ -1064,47 +1063,18 @@ impl crate::Context for Context {
}
}

fn surface_get_supported_formats(
fn surface_get_capabilities(
&self,
surface: &Self::SurfaceId,
adapter: &Self::AdapterId,
) -> Vec<TextureFormat> {
) -> wgt::SurfaceCapabilities {
let global = &self.0;
match wgc::gfx_select!(adapter => global.surface_get_supported_formats(surface.id, *adapter))
{
Ok(formats) => formats,
Err(wgc::instance::GetSurfaceSupportError::Unsupported) => vec![],
Err(err) => self.handle_error_fatal(err, "Surface::get_supported_formats"),
}
}

fn surface_get_supported_present_modes(
&self,
surface: &Self::SurfaceId,
adapter: &Self::AdapterId,
) -> Vec<PresentMode> {
let global = &self.0;
match wgc::gfx_select!(adapter => global.surface_get_supported_present_modes(surface.id, *adapter))
{
Ok(modes) => modes,
Err(wgc::instance::GetSurfaceSupportError::Unsupported) => vec![],
Err(err) => self.handle_error_fatal(err, "Surface::get_supported_present_modes"),
}
}

fn surface_get_supported_alpha_modes(
&self,
surface: &Self::SurfaceId,
adapter: &Self::AdapterId,
) -> Vec<CompositeAlphaMode> {
let global = &self.0;
match wgc::gfx_select!(adapter => global.surface_get_supported_alpha_modes(surface.id, *adapter))
{
Ok(modes) => modes,
match wgc::gfx_select!(adapter => global.surface_get_capabilities(surface.id, *adapter)) {
Ok(caps) => caps,
Err(wgc::instance::GetSurfaceSupportError::Unsupported) => {
vec![CompositeAlphaMode::Opaque]
wgt::SurfaceCapabilities::default()
}
Err(err) => self.handle_error_fatal(err, "Surface::get_supported_alpha_modes"),
Err(err) => self.handle_error_fatal(err, "Surface::get_supported_formats"),
}
}

Expand Down
37 changes: 13 additions & 24 deletions wgpu/src/backend/web.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1322,33 +1322,22 @@ impl crate::Context for Context {
format.describe().guaranteed_format_features
}

fn surface_get_supported_formats(
fn surface_get_capabilities(
&self,
_surface: &Self::SurfaceId,
_adapter: &Self::AdapterId,
) -> Vec<wgt::TextureFormat> {
// https://gpuweb.github.io/gpuweb/#supported-context-formats
vec![
wgt::TextureFormat::Bgra8Unorm,
wgt::TextureFormat::Rgba8Unorm,
wgt::TextureFormat::Rgba16Float,
]
}

fn surface_get_supported_present_modes(
&self,
_surface: &Self::SurfaceId,
_adapter: &Self::AdapterId,
) -> Vec<wgt::PresentMode> {
vec![wgt::PresentMode::Fifo]
}

fn surface_get_supported_alpha_modes(
&self,
_surface: &Self::SurfaceId,
_adapter: &Self::AdapterId,
) -> Vec<wgt::CompositeAlphaMode> {
vec![wgt::CompositeAlphaMode::Opaque]
) -> wgt::SurfaceCapabilities {
wgt::SurfaceCapabilities {
// https://gpuweb.github.io/gpuweb/#supported-context-formats
formats: vec![
wgt::TextureFormat::Bgra8Unorm,
wgt::TextureFormat::Rgba8Unorm,
wgt::TextureFormat::Rgba16Float,
],
// Doesn't really have meaning on the web.
present_modes: vec![wgt::PresentMode::Fifo],
alpha_modes: vec![wgt::CompositeAlphaMode::Opaque],
}
}

fn surface_configure(
Expand Down
Loading