Change get_preferred_format to get_supported_formats (#2783)

* 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 <connorwadefitzgerald@gmail.com>

Co-authored-by: Connor Fitzgerald <connorwadefitzgerald@gmail.com>
This commit is contained in:
Steven 2022-06-17 21:21:02 -07:00 committed by GitHub
parent aba7197fe8
commit 0d4d3f4ceb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 49 additions and 91 deletions

View File

@ -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();
@ -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>(

View File

@ -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");
@ -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)
}
}

View File

@ -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,

View File

@ -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,

View File

@ -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,

View File

@ -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"),
}
}

View File

@ -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 {
@ -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(

View File

@ -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,
@ -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.