Move get_swap_chain_preferred_format from device to adapter and check formats

Squashed commit of the following:

commit 16e9c89dbccda3e37d05f7548dc8b9ddfb1d8613
Author: Niklas Korz <niklas@niklaskorz.de>
Date:   Mon Jan 11 19:15:43 2021 +0100

    format

commit 8c69a70ec22427b6a030915e06654bb0fc9b3c69
Author: Niklas Korz <niklas@niklaskorz.de>
Date:   Mon Jan 11 19:12:24 2021 +0100

    Implement Global::adapter_get_swap_chain_preferred_format

commit 63efae1cff508d060eaa6ccafe80c02af6af21f4
Author: Niklas Korz <niklas@niklaskorz.de>
Date:   Mon Jan 11 17:25:42 2021 +0100

    Move get_swap_chain_preferred_format to adapter

commit 1e72a876994820aec9b18f9dac7f1a9ae82d7cee
Author: Niklas Korz <niklas@niklaskorz.de>
Date:   Mon Jan 11 15:49:10 2021 +0100

    Add fallback to device_get_swap_chain_preferred_format
This commit is contained in:
Niklas Korz
2021-01-11 19:50:32 +01:00
parent 5a29e010e2
commit ac98c0bdfa
2 changed files with 73 additions and 12 deletions

View File

@@ -8,7 +8,7 @@ use crate::{
hub::{
GfxBackend, Global, GlobalIdentityHandlerFactory, Hub, Input, InvalidId, Storage, Token,
},
id, pipeline, resource, span, swap_chain,
id, instance, pipeline, resource, span, swap_chain,
track::{BufferState, TextureSelector, TextureState, TrackerSet},
validation::{self, check_buffer_usage, check_texture_usage},
FastHashMap, FastHashSet, Label, LabelHelpers, LifeGuard, MultiRefCount, PrivateFeatures,
@@ -2379,6 +2379,28 @@ pub struct ImplicitPipelineIds<'a, G: GlobalIdentityHandlerFactory> {
}
impl<G: GlobalIdentityHandlerFactory> Global<G> {
pub fn adapter_get_swap_chain_preferred_format<B: GfxBackend>(
&self,
adapter_id: id::AdapterId,
surface_id: id::SurfaceId,
) -> Result<TextureFormat, instance::GetSwapChainPreferredFormatError> {
span!(_guard, INFO, "Adapter::get_swap_chain_preferred_format");
let hub = B::hub(self);
let mut token = Token::root();
let (mut surface_guard, mut token) = self.surfaces.write(&mut token);
let (adapter_guard, mut _token) = hub.adapters.read(&mut token);
let adapter = adapter_guard
.get(adapter_id)
.map_err(|_| instance::GetSwapChainPreferredFormatError::InvalidAdapter)?;
let surface = surface_guard
.get_mut(surface_id)
.map_err(|_| instance::GetSwapChainPreferredFormatError::InvalidSurface)?;
adapter.get_swap_chain_preferred_format(surface)
}
pub fn device_features<B: GfxBackend>(
&self,
device_id: id::DeviceId,
@@ -3885,17 +3907,6 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
.push(layout_id);
}
pub fn device_get_swap_chain_preferred_format<B: GfxBackend>(
&self,
_device_id: id::DeviceId,
) -> Result<TextureFormat, InvalidDevice> {
span!(_guard, INFO, "Device::get_swap_chain_preferred_format");
//TODO: we can query the formats like done in `device_create_swapchain`,
// but its not clear which format in the list to return.
// For now, return `Bgra8UnormSrgb` that we know is supported everywhere.
Ok(TextureFormat::Bgra8UnormSrgb)
}
pub fn device_create_swap_chain<B: GfxBackend>(
&self,
device_id: id::DeviceId,

View File

@@ -250,6 +250,44 @@ impl<B: GfxBackend> Adapter<B> {
}
}
pub fn get_swap_chain_preferred_format(
&self,
surface: &mut Surface,
) -> Result<wgt::TextureFormat, GetSwapChainPreferredFormatError> {
span!(_guard, INFO, "Adapter::get_swap_chain_preferred_format");
let formats = {
let surface = B::get_surface_mut(surface);
let queue_family = &self.raw.queue_families[0];
if !surface.supports_queue_family(queue_family) {
return Err(GetSwapChainPreferredFormatError::UnsupportedQueueFamily);
}
surface.supported_formats(&self.raw.physical_device)
};
if let Some(formats) = formats {
// Check the four formats mentioned in the WebGPU spec:
// Bgra8UnormSrgb, Rgba8UnormSrgb, Bgra8Unorm, Rgba8Unorm
// Also, prefer sRGB over linear as it is better in
// representing perceived colors.
if formats.contains(&hal::format::Format::Bgra8Srgb) {
return Ok(wgt::TextureFormat::Bgra8UnormSrgb);
}
if formats.contains(&hal::format::Format::Rgba8Srgb) {
return Ok(wgt::TextureFormat::Rgba8UnormSrgb);
}
if formats.contains(&hal::format::Format::Bgra8Unorm) {
return Ok(wgt::TextureFormat::Bgra8Unorm);
}
if formats.contains(&hal::format::Format::Rgba8Unorm) {
return Ok(wgt::TextureFormat::Rgba8Unorm);
}
return Err(GetSwapChainPreferredFormatError::NotFound);
}
// If no formats were returned, use Bgra8UnormSrgb
Ok(wgt::TextureFormat::Bgra8UnormSrgb)
}
pub(crate) fn get_texture_format_features(
&self,
format: wgt::TextureFormat,
@@ -448,6 +486,18 @@ impl<B: hal::Backend> crate::hub::Resource for Adapter<B> {
}
}
#[derive(Clone, Debug, Error)]
pub enum GetSwapChainPreferredFormatError {
#[error("no suitable format found")]
NotFound,
#[error("invalid adapter")]
InvalidAdapter,
#[error("invalid surface")]
InvalidSurface,
#[error("surface does not support the adapter's queue family")]
UnsupportedQueueFamily,
}
#[derive(Clone, Debug, Error)]
/// Error when requesting a device from the adaptor
pub enum RequestDeviceError {