diff --git a/wgpu/examples/framework.rs b/wgpu/examples/framework.rs index d448b93bbd..8a50567cc2 100644 --- a/wgpu/examples/framework.rs +++ b/wgpu/examples/framework.rs @@ -224,12 +224,7 @@ fn start( let mut sc_desc = wgpu::SwapChainDescriptor { usage: wgpu::TextureUsage::RENDER_ATTACHMENT, - // TODO: Allow srgb unconditionally - format: if cfg!(target_arch = "wasm32") { - wgpu::TextureFormat::Bgra8Unorm - } else { - wgpu::TextureFormat::Bgra8UnormSrgb - }, + format: device.get_swap_chain_preferred_format(), width: size.width, height: size.height, present_mode: wgpu::PresentMode::Mailbox, diff --git a/wgpu/examples/hello-triangle/main.rs b/wgpu/examples/hello-triangle/main.rs index 7ce41c0387..97a917dbf1 100644 --- a/wgpu/examples/hello-triangle/main.rs +++ b/wgpu/examples/hello-triangle/main.rs @@ -5,7 +5,7 @@ use winit::{ window::Window, }; -async fn run(event_loop: EventLoop<()>, window: Window, swapchain_format: wgpu::TextureFormat) { +async fn run(event_loop: EventLoop<()>, window: Window) { let size = window.inner_size(); let instance = wgpu::Instance::new(wgpu::BackendBit::PRIMARY); let surface = unsafe { instance.create_surface(&window) }; @@ -44,6 +44,8 @@ async fn run(event_loop: EventLoop<()>, window: Window, swapchain_format: wgpu:: push_constant_ranges: &[], }); + let swapchain_format = device.get_swap_chain_preferred_format(); + let render_pipeline = device.create_render_pipeline(&wgpu::RenderPipelineDescriptor { label: None, layout: Some(&pipeline_layout), @@ -138,7 +140,7 @@ fn main() { { subscriber::initialize_default_subscriber(None); // Temporarily avoid srgb formats for the swapchain on the web - futures::executor::block_on(run(event_loop, window, wgpu::TextureFormat::Bgra8UnormSrgb)); + futures::executor::block_on(run(event_loop, window)); } #[cfg(target_arch = "wasm32")] { @@ -154,6 +156,6 @@ fn main() { .ok() }) .expect("couldn't append canvas to document body"); - wasm_bindgen_futures::spawn_local(run(event_loop, window, wgpu::TextureFormat::Bgra8Unorm)); + wasm_bindgen_futures::spawn_local(run(event_loop, window)); } } diff --git a/wgpu/examples/hello-windows/main.rs b/wgpu/examples/hello-windows/main.rs index 42f098cb14..70c849be5d 100644 --- a/wgpu/examples/hello-windows/main.rs +++ b/wgpu/examples/hello-windows/main.rs @@ -27,12 +27,12 @@ impl ViewportDesc { } } - fn build(self, device: &wgpu::Device, swapchain_format: wgpu::TextureFormat) -> Viewport { + fn build(self, device: &wgpu::Device) -> Viewport { let size = self.window.inner_size(); let sc_desc = wgpu::SwapChainDescriptor { usage: wgpu::TextureUsage::RENDER_ATTACHMENT, - format: swapchain_format, + format: device.get_swap_chain_preferred_format(), width: size.width, height: size.height, present_mode: wgpu::PresentMode::Fifo, @@ -62,11 +62,7 @@ impl Viewport { } } -async fn run( - event_loop: EventLoop<()>, - viewports: Vec<(Window, wgpu::Color)>, - swapchain_format: wgpu::TextureFormat, -) { +async fn run(event_loop: EventLoop<()>, viewports: Vec<(Window, wgpu::Color)>) { let instance = wgpu::Instance::new(wgpu::BackendBit::PRIMARY); let viewports: Vec<_> = viewports .into_iter() @@ -96,7 +92,7 @@ async fn run( let mut viewports: HashMap = viewports .into_iter() - .map(|desc| (desc.window.id(), desc.build(&device, swapchain_format))) + .map(|desc| (desc.window.id(), desc.build(&device))) .collect(); event_loop.run(move |event, _, control_flow| { @@ -195,11 +191,7 @@ fn main() { subscriber::initialize_default_subscriber(None); // Temporarily avoid srgb formats for the swapchain on the web - futures::executor::block_on(run( - event_loop, - viewports, - wgpu::TextureFormat::Bgra8UnormSrgb, - )); + futures::executor::block_on(run(event_loop, viewports)); } #[cfg(target_arch = "wasm32")] { diff --git a/wgpu/src/backend/direct.rs b/wgpu/src/backend/direct.rs index f5ef5ee128..bf9b965524 100644 --- a/wgpu/src/backend/direct.rs +++ b/wgpu/src/backend/direct.rs @@ -4,7 +4,7 @@ use crate::{ CommandEncoderDescriptor, ComputePassDescriptor, ComputePipelineDescriptor, Features, Label, Limits, LoadOp, MapMode, Operations, PipelineLayoutDescriptor, RenderBundleEncoderDescriptor, RenderPipelineDescriptor, SamplerDescriptor, ShaderModuleDescriptor, ShaderSource, - SwapChainStatus, TextureDescriptor, TextureViewDescriptor, + SwapChainStatus, TextureDescriptor, TextureFormat, TextureViewDescriptor, }; use arrayvec::ArrayVec; @@ -707,6 +707,15 @@ impl crate::Context for Context { } } + fn device_get_swap_chain_preferred_format(&self, device: &Self::DeviceId) -> TextureFormat { + let global = &self.0; + match wgc::gfx_select!(device.id => global.device_get_swap_chain_preferred_format(device.id)) + { + Ok(swap_chain_preferred_format) => swap_chain_preferred_format, + Err(err) => self.handle_error_fatal(err, "Device::get_swap_chain_preferred_format"), + } + } + fn device_create_swap_chain( &self, device: &Self::DeviceId, diff --git a/wgpu/src/backend/web.rs b/wgpu/src/backend/web.rs index 5b5975aeeb..8333575f6b 100644 --- a/wgpu/src/backend/web.rs +++ b/wgpu/src/backend/web.rs @@ -962,6 +962,14 @@ impl crate::Context for Context { wgt::Limits::default() } + fn device_get_swap_chain_preferred_format( + &self, + device: &Self::DeviceId, + ) -> wgt::TextureFormat { + // TODO: web-sys bindings need to be updated to not return a promise + wgt::TextureFormat::Bgra8Unorm + } + fn device_create_swap_chain( &self, device: &Self::DeviceId, diff --git a/wgpu/src/lib.rs b/wgpu/src/lib.rs index 7fe3d51434..f361192399 100644 --- a/wgpu/src/lib.rs +++ b/wgpu/src/lib.rs @@ -196,6 +196,7 @@ trait Context: Debug + Send + Sized + Sync { fn device_features(&self, device: &Self::DeviceId) -> Features; fn device_limits(&self, device: &Self::DeviceId) -> Limits; + fn device_get_swap_chain_preferred_format(&self, device: &Self::DeviceId) -> TextureFormat; fn device_create_swap_chain( &self, device: &Self::DeviceId, @@ -1428,6 +1429,11 @@ impl Device { Context::device_limits(&*self.context, &self.id) } + /// Returns an optimal texture format to use for the [`SwapChain`] with this device. + pub fn get_swap_chain_preferred_format(&self) -> TextureFormat { + Context::device_get_swap_chain_preferred_format(&*self.context, &self.id) + } + /// Creates a shader module from either SPIR-V or WGSL source code. pub fn create_shader_module(&self, desc: &ShaderModuleDescriptor) -> ShaderModule { ShaderModule {