Skip to content

Commit

Permalink
Change get_preferred_format to get_supported_formats (#2783)
Browse files Browse the repository at this point in the history
* Change all the functions

* Return the set of supported TextureFormat specified by WebGPU

* Remove redundant filtering and use list directly

* Replace pops with first

* Remove now unused function

* Fix doc and clarify preffered format

* Dereference enums

* Remove unused list

* Remove fancy coode

* Update wgpu-core/src/device/mod.rs

Co-authored-by: Connor Fitzgerald <[email protected]>

Co-authored-by: Connor Fitzgerald <[email protected]>
  • Loading branch information
stevenhuyn and cwfitzgerald authored Jun 18, 2022
1 parent aba7197 commit 0d4d3f4
Show file tree
Hide file tree
Showing 8 changed files with 49 additions and 91 deletions.
8 changes: 4 additions & 4 deletions wgpu-core/src/device/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3105,12 +3105,12 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
.map_err(|_| instance::IsSurfaceSupportedError::InvalidSurface)?;
Ok(adapter.is_surface_supported(surface))
}
pub fn surface_get_preferred_format<A: HalApi>(
pub fn surface_get_supported_formats<A: HalApi>(
&self,
surface_id: id::SurfaceId,
adapter_id: id::AdapterId,
) -> Result<TextureFormat, instance::GetSurfacePreferredFormatError> {
profiling::scope!("surface_get_preferred_format");
) -> Result<Vec<TextureFormat>, instance::GetSurfacePreferredFormatError> {
profiling::scope!("Surface::get_supported_formats");
let hub = A::hub(self);
let mut token = Token::root();

Expand All @@ -3123,7 +3123,7 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
.get(surface_id)
.map_err(|_| instance::GetSurfacePreferredFormatError::InvalidSurface)?;

surface.get_preferred_format(adapter)
surface.get_supported_formats(adapter)
}

pub fn device_features<A: HalApi>(
Expand Down
25 changes: 7 additions & 18 deletions wgpu-core/src/instance.rs
Original file line number Diff line number Diff line change
Expand Up @@ -152,21 +152,10 @@ impl crate::hub::Resource for Surface {
}

impl Surface {
pub fn get_preferred_format<A: HalApi>(
pub fn get_supported_formats<A: HalApi>(
&self,
adapter: &Adapter<A>,
) -> Result<wgt::TextureFormat, GetSurfacePreferredFormatError> {
// Check the four formats mentioned in the WebGPU spec.
// Also, prefer sRGB over linear as it is better in
// representing perceived colors.
let preferred_formats = [
wgt::TextureFormat::Bgra8UnormSrgb,
wgt::TextureFormat::Rgba8UnormSrgb,
wgt::TextureFormat::Bgra8Unorm,
wgt::TextureFormat::Rgba8Unorm,
wgt::TextureFormat::Rgba16Float,
];

) -> Result<Vec<wgt::TextureFormat>, GetSurfacePreferredFormatError> {
let suf = A::get_surface(self);
let caps = unsafe {
profiling::scope!("surface_capabilities");
Expand All @@ -177,11 +166,11 @@ impl Surface {
.ok_or(GetSurfacePreferredFormatError::UnsupportedQueueFamily)?
};

preferred_formats
.iter()
.cloned()
.find(|preferred| caps.formats.contains(preferred))
.ok_or(GetSurfacePreferredFormatError::NotFound)
if caps.formats.is_empty() {
return Err(GetSurfacePreferredFormatError::NotFound);
}

Ok(caps.formats)
}
}

Expand Down
6 changes: 5 additions & 1 deletion wgpu/examples/framework.rs
Original file line number Diff line number Diff line change
Expand Up @@ -269,7 +269,11 @@ fn start<E: Example>(
let spawner = Spawner::new();
let mut config = wgpu::SurfaceConfiguration {
usage: wgpu::TextureUsages::RENDER_ATTACHMENT,
format: surface.get_preferred_format(&adapter).unwrap(),
format: *surface
.get_supported_formats(&adapter)
.unwrap()
.first()
.unwrap(),
width: size.width,
height: size.height,
present_mode: wgpu::PresentMode::Mailbox,
Expand Down
6 changes: 5 additions & 1 deletion wgpu/examples/hello-triangle/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,11 @@ async fn run(event_loop: EventLoop<()>, window: Window) {
push_constant_ranges: &[],
});

let swapchain_format = surface.get_preferred_format(&adapter).unwrap();
let swapchain_format = *surface
.get_supported_formats(&adapter)
.unwrap()
.first()
.unwrap();

let render_pipeline = device.create_render_pipeline(&wgpu::RenderPipelineDescriptor {
label: None,
Expand Down
7 changes: 6 additions & 1 deletion wgpu/examples/hello-windows/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,12 @@ impl ViewportDesc {

let config = wgpu::SurfaceConfiguration {
usage: wgpu::TextureUsages::RENDER_ATTACHMENT,
format: self.surface.get_preferred_format(adapter).unwrap(),
format: *self
.surface
.get_supported_formats(adapter)
.unwrap()
.first()
.unwrap(),
width: size.width,
height: size.height,
present_mode: wgpu::PresentMode::Fifo,
Expand Down
10 changes: 5 additions & 5 deletions wgpu/src/backend/direct.rs
Original file line number Diff line number Diff line change
Expand Up @@ -958,17 +958,17 @@ impl crate::Context for Context {
}
}

fn surface_get_preferred_format(
fn surface_get_supported_formats(
&self,
surface: &Self::SurfaceId,
adapter: &Self::AdapterId,
) -> Option<TextureFormat> {
) -> Option<Vec<TextureFormat>> {
let global = &self.0;
match wgc::gfx_select!(adapter => global.surface_get_preferred_format(surface.id, *adapter))
match wgc::gfx_select!(adapter => global.surface_get_supported_formats(surface.id, *adapter))
{
Ok(format) => Some(format),
Ok(formats) => Some(formats),
Err(wgc::instance::GetSurfacePreferredFormatError::UnsupportedQueueFamily) => None,
Err(err) => self.handle_error_fatal(err, "Surface::get_preferred_format"),
Err(err) => self.handle_error_fatal(err, "Surface::get_supported_formats"),
}
}

Expand Down
67 changes: 11 additions & 56 deletions wgpu/src/backend/web.rs
Original file line number Diff line number Diff line change
Expand Up @@ -553,56 +553,6 @@ fn map_texture_format(texture_format: wgt::TextureFormat) -> web_sys::GpuTexture
}
}

fn map_texture_format_from_web_sys(
texture_format: web_sys::GpuTextureFormat,
) -> wgt::TextureFormat {
use web_sys::GpuTextureFormat as tf;
use wgt::TextureFormat;
match texture_format {
tf::R8unorm => TextureFormat::R8Unorm,
tf::R8snorm => TextureFormat::R8Snorm,
tf::R8uint => TextureFormat::R8Uint,
tf::R8sint => TextureFormat::R8Sint,
tf::R16uint => TextureFormat::R16Uint,
tf::R16sint => TextureFormat::R16Sint,
tf::R16float => TextureFormat::R16Float,
tf::Rg8unorm => TextureFormat::Rg8Unorm,
tf::Rg8snorm => TextureFormat::Rg8Snorm,
tf::Rg8uint => TextureFormat::Rg8Uint,
tf::Rg8sint => TextureFormat::Rg8Sint,
tf::R32uint => TextureFormat::R32Uint,
tf::R32sint => TextureFormat::R32Sint,
tf::R32float => TextureFormat::R32Float,
tf::Rg16uint => TextureFormat::Rg16Uint,
tf::Rg16sint => TextureFormat::Rg16Sint,
tf::Rg16float => TextureFormat::Rg16Float,
tf::Rgba8unorm => TextureFormat::Rgba8Unorm,
tf::Rgba8unormSrgb => TextureFormat::Rgba8UnormSrgb,
tf::Rgba8snorm => TextureFormat::Rgba8Snorm,
tf::Rgba8uint => TextureFormat::Rgba8Uint,
tf::Rgba8sint => TextureFormat::Rgba8Sint,
tf::Bgra8unorm => TextureFormat::Bgra8Unorm,
tf::Bgra8unormSrgb => TextureFormat::Bgra8UnormSrgb,
tf::Rgb10a2unorm => TextureFormat::Rgb10a2Unorm,
tf::Rg11b10ufloat => TextureFormat::Rg11b10Float,
tf::Rg32uint => TextureFormat::Rg32Uint,
tf::Rg32sint => TextureFormat::Rg32Sint,
tf::Rg32float => TextureFormat::Rg32Float,
tf::Rgba16uint => TextureFormat::Rgba16Uint,
tf::Rgba16sint => TextureFormat::Rgba16Sint,
tf::Rgba16float => TextureFormat::Rgba16Float,
tf::Rgba32uint => TextureFormat::Rgba32Uint,
tf::Rgba32sint => TextureFormat::Rgba32Sint,
tf::Rgba32float => TextureFormat::Rgba32Float,
tf::Depth32float => TextureFormat::Depth32Float,
tf::Depth32floatStencil8 => TextureFormat::Depth32FloatStencil8,
tf::Depth24plus => TextureFormat::Depth24Plus,
tf::Depth24plusStencil8 => TextureFormat::Depth24PlusStencil8,
tf::Depth24unormStencil8 => TextureFormat::Depth24UnormStencil8,
_ => unimplemented!(),
}
}

fn map_texture_component_type(
sample_type: wgt::TextureSampleType,
) -> web_sys::GpuTextureSampleType {
Expand Down Expand Up @@ -1188,13 +1138,18 @@ impl crate::Context for Context {
format.describe().guaranteed_format_features
}

fn surface_get_preferred_format(
fn surface_get_supported_formats(
&self,
surface: &Self::SurfaceId,
adapter: &Self::AdapterId,
) -> Option<wgt::TextureFormat> {
let format = map_texture_format_from_web_sys(surface.0.get_preferred_format(&adapter.0));
Some(format)
_surface: &Self::SurfaceId,
_adapter: &Self::AdapterId,
) -> Option<Vec<wgt::TextureFormat>> {
// https://gpuweb.github.io/gpuweb/#supported-context-formats
let formats = vec![
wgt::TextureFormat::Bgra8Unorm,
wgt::TextureFormat::Rgba8Unorm,
wgt::TextureFormat::Rgba16Float,
];
Some(formats)
}

fn surface_configure(
Expand Down
11 changes: 6 additions & 5 deletions wgpu/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -225,11 +225,11 @@ trait Context: Debug + Send + Sized + Sync {
format: TextureFormat,
) -> TextureFormatFeatures;

fn surface_get_preferred_format(
fn surface_get_supported_formats(
&self,
surface: &Self::SurfaceId,
adapter: &Self::AdapterId,
) -> Option<TextureFormat>;
) -> Option<Vec<TextureFormat>>;
fn surface_configure(
&self,
surface: &Self::SurfaceId,
Expand Down Expand Up @@ -3446,11 +3446,12 @@ impl Drop for SurfaceTexture {
}

impl Surface {
/// Returns an optimal texture format to use for the [`Surface`] with this adapter.
/// Returns a vec of supported texture formats to use for the [`Surface`] with this adapter.
/// Note: The first format in the vector is preferred
///
/// Returns None if the surface is incompatible with the adapter.
pub fn get_preferred_format(&self, adapter: &Adapter) -> Option<TextureFormat> {
Context::surface_get_preferred_format(&*self.context, &self.id, &adapter.id)
pub fn get_supported_formats(&self, adapter: &Adapter) -> Option<Vec<TextureFormat>> {
Context::surface_get_supported_formats(&*self.context, &self.id, &adapter.id)
}

/// Initializes [`Surface`] for presentation.
Expand Down

0 comments on commit 0d4d3f4

Please sign in to comment.