Skip to content

Commit

Permalink
Unify Surface Capabilities APIs under one function call
Browse files Browse the repository at this point in the history
  • Loading branch information
cwfitzgerald committed Nov 27, 2022
1 parent d7fe7ef commit 84cb3e6
Show file tree
Hide file tree
Showing 9 changed files with 99 additions and 167 deletions.
17 changes: 17 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,22 @@ 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;
```

### Changes

#### General
Expand All @@ -48,6 +64,7 @@ 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)

#### 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 @@ -3225,43 +3225,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 @@ -3883,6 +3883,33 @@ bitflags::bitflags! {

impl_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
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

0 comments on commit 84cb3e6

Please sign in to comment.