From 9348e9364efbb5e33c9a82b685170f7ae33347a3 Mon Sep 17 00:00:00 2001 From: Andreas Reich Date: Wed, 5 Oct 2022 19:19:40 +0200 Subject: [PATCH 1/4] webgl backend supports now non-srgb framebuffer --- wgpu-hal/src/gles/adapter.rs | 13 ++++ .../{present.frag => srgb_present.frag} | 0 .../{present.vert => srgb_present.vert} | 0 wgpu-hal/src/gles/web.rs | 67 +++++++++++++------ 4 files changed, 59 insertions(+), 21 deletions(-) rename wgpu-hal/src/gles/shaders/{present.frag => srgb_present.frag} (100%) rename wgpu-hal/src/gles/shaders/{present.vert => srgb_present.vert} (100%) diff --git a/wgpu-hal/src/gles/adapter.rs b/wgpu-hal/src/gles/adapter.rs index 2ae01cd2a0..faac18a65a 100644 --- a/wgpu-hal/src/gles/adapter.rs +++ b/wgpu-hal/src/gles/adapter.rs @@ -807,6 +807,19 @@ impl crate::Adapter for super::Adapter { formats.push(wgt::TextureFormat::Rgba16Float) } if surface.presentable { + let mut formats = vec![ + wgt::TextureFormat::Rgba8Unorm, + #[cfg(not(target_arch = "wasm32"))] + wgt::TextureFormat::Bgra8Unorm, + ]; + if surface.supports_srgb() { + formats.extend(&[ + wgt::TextureFormat::Rgba8UnormSrgb, + #[cfg(not(target_arch = "wasm32"))] + wgt::TextureFormat::Bgra8UnormSrgb, + ]) + } + Some(crate::SurfaceCapabilities { formats, present_modes: vec![wgt::PresentMode::Fifo], //TODO diff --git a/wgpu-hal/src/gles/shaders/present.frag b/wgpu-hal/src/gles/shaders/srgb_present.frag similarity index 100% rename from wgpu-hal/src/gles/shaders/present.frag rename to wgpu-hal/src/gles/shaders/srgb_present.frag diff --git a/wgpu-hal/src/gles/shaders/present.vert b/wgpu-hal/src/gles/shaders/srgb_present.vert similarity index 100% rename from wgpu-hal/src/gles/shaders/present.vert rename to wgpu-hal/src/gles/shaders/srgb_present.vert diff --git a/wgpu-hal/src/gles/web.rs b/wgpu-hal/src/gles/web.rs index 11eeb30d23..130da483e6 100644 --- a/wgpu-hal/src/gles/web.rs +++ b/wgpu-hal/src/gles/web.rs @@ -43,7 +43,7 @@ impl Instance { Ok(Surface { webgl2_context, - present_program: None, + srgb_present_program: None, swapchain: None, texture: None, presentable: true, @@ -64,7 +64,7 @@ impl Instance { Ok(Surface { webgl2_context, - present_program: None, + srgb_present_program: None, swapchain: None, texture: None, presentable: true, @@ -144,7 +144,7 @@ pub struct Surface { pub(super) swapchain: Option, texture: Option, pub(super) presentable: bool, - present_program: Option, + srgb_present_program: Option, } // SAFE: Because web doesn't have threads ( yet ) @@ -166,35 +166,59 @@ impl Surface { _suf_texture: super::Texture, gl: &glow::Context, ) -> Result<(), crate::SurfaceError> { - gl.bind_framebuffer(glow::DRAW_FRAMEBUFFER, None); - gl.bind_sampler(0, None); - gl.active_texture(glow::TEXTURE0); - gl.bind_texture(glow::TEXTURE_2D, self.texture); - gl.use_program(self.present_program); - gl.disable(glow::DEPTH_TEST); - gl.disable(glow::STENCIL_TEST); - gl.disable(glow::SCISSOR_TEST); - gl.disable(glow::BLEND); - gl.disable(glow::CULL_FACE); - gl.draw_buffers(&[glow::BACK]); - gl.draw_arrays(glow::TRIANGLES, 0, 3); + let swapchain = self.swapchain.as_ref().ok_or(crate::SurfaceError::Other( + "need to configure surface before presenting", + ))?; + + if swapchain.format.describe().srgb { + gl.bind_framebuffer(glow::DRAW_FRAMEBUFFER, None); + gl.bind_sampler(0, None); + gl.active_texture(glow::TEXTURE0); + gl.bind_texture(glow::TEXTURE_2D, self.texture); + gl.use_program(self.srgb_present_program); + gl.disable(glow::DEPTH_TEST); + gl.disable(glow::STENCIL_TEST); + gl.disable(glow::SCISSOR_TEST); + gl.disable(glow::BLEND); + gl.disable(glow::CULL_FACE); + gl.draw_buffers(&[glow::BACK]); + gl.draw_arrays(glow::TRIANGLES, 0, 3); + } else { + gl.bind_framebuffer(glow::READ_FRAMEBUFFER, Some(swapchain.framebuffer)); + gl.bind_framebuffer(glow::DRAW_FRAMEBUFFER, None); + // Note the Y-flipping here. GL's presentation is not flipped, + // but main rendering is. Therefore, we Y-flip the output positions + // in the shader, and also this blit. + gl.blit_framebuffer( + 0, + swapchain.extent.height as i32, + swapchain.extent.width as i32, + 0, + 0, + 0, + swapchain.extent.width as i32, + swapchain.extent.height as i32, + glow::COLOR_BUFFER_BIT, + glow::NEAREST, + ); + } Ok(()) } - unsafe fn create_present_program(gl: &glow::Context) -> glow::Program { + unsafe fn create_srgb_present_program(gl: &glow::Context) -> glow::Program { let program = gl .create_program() .expect("Could not create shader program"); let vertex = gl .create_shader(glow::VERTEX_SHADER) .expect("Could not create shader"); - gl.shader_source(vertex, include_str!("./shaders/present.vert")); + gl.shader_source(vertex, include_str!("./shaders/srgb_present.vert")); gl.compile_shader(vertex); let fragment = gl .create_shader(glow::FRAGMENT_SHADER) .expect("Could not create shader"); - gl.shader_source(fragment, include_str!("./shaders/present.frag")); + gl.shader_source(fragment, include_str!("./shaders/srgb_present.frag")); gl.compile_shader(fragment); gl.attach_shader(program, vertex); gl.attach_shader(program, fragment); @@ -207,7 +231,8 @@ impl Surface { } pub fn supports_srgb(&self) -> bool { - true // WebGL only supports sRGB + // present.frag takes care of handling srgb conversion + true } } @@ -224,8 +249,8 @@ impl crate::Surface for Surface { gl.delete_framebuffer(swapchain.framebuffer); } - if self.present_program.is_none() { - self.present_program = Some(Self::create_present_program(gl)); + if self.srgb_present_program.is_none() && config.format.describe().srgb { + self.srgb_present_program = Some(Self::create_srgb_present_program(gl)); } if let Some(texture) = self.texture.take() { From eaad2ee79643c30eef4194092df3b79119210fe6 Mon Sep 17 00:00:00 2001 From: Andreas Reich Date: Thu, 6 Oct 2022 11:13:54 +0200 Subject: [PATCH 2/4] update changelog --- CHANGELOG.md | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 10ea5b3b12..d01d1a4671 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -49,7 +49,13 @@ Bottom level categories: ### Added/New Features -Add the `"wgsl"` feature, to enable WGSL shaders in `wgpu-core` and `wgpu`. Enabled by default in `wgpu`. By @daxpedda in [#2890](https://github.com/gfx-rs/wgpu/pull/2890). +#### General + +- Add the `"wgsl"` feature, to enable WGSL shaders in `wgpu-core` and `wgpu`. Enabled by default in `wgpu`. By @daxpedda in [#2890](https://github.com/gfx-rs/wgpu/pull/2890). + +#### GLES + +- Surfaces support now `TextureFormat::Rgba8Unorm` and (non-web only) `TextureFormat::Bgra8Unorm` ### Bug Fixes From 64841939453b9af4ec0b4f9807de0b4b17af1be0 Mon Sep 17 00:00:00 2001 From: Andreas Reich Date: Fri, 7 Oct 2022 09:30:56 +0200 Subject: [PATCH 3/4] [gles] fix duplicated surface compat format computation disable f16 for webgl for now again --- wgpu-hal/src/gles/adapter.rs | 28 ++++++++-------------------- 1 file changed, 8 insertions(+), 20 deletions(-) diff --git a/wgpu-hal/src/gles/adapter.rs b/wgpu-hal/src/gles/adapter.rs index faac18a65a..3730fddaa5 100644 --- a/wgpu-hal/src/gles/adapter.rs +++ b/wgpu-hal/src/gles/adapter.rs @@ -786,26 +786,6 @@ impl crate::Adapter for super::Adapter { &self, surface: &super::Surface, ) -> Option { - let mut formats = if surface.supports_srgb() { - vec![ - wgt::TextureFormat::Rgba8UnormSrgb, - #[cfg(not(target_arch = "wasm32"))] - wgt::TextureFormat::Bgra8UnormSrgb, - ] - } else { - vec![ - wgt::TextureFormat::Rgba8Unorm, - #[cfg(not(target_arch = "wasm32"))] - wgt::TextureFormat::Bgra8Unorm, - ] - }; - if self - .shared - .private_caps - .contains(super::PrivateCapabilities::COLOR_BUFFER_HALF_FLOAT) - { - formats.push(wgt::TextureFormat::Rgba16Float) - } if surface.presentable { let mut formats = vec![ wgt::TextureFormat::Rgba8Unorm, @@ -819,6 +799,14 @@ impl crate::Adapter for super::Adapter { wgt::TextureFormat::Bgra8UnormSrgb, ]) } + #[cfg(not(target_arch = "wasm32"))] + if self + .shared + .private_caps + .contains(super::PrivateCapabilities::COLOR_BUFFER_HALF_FLOAT) + { + formats.push(wgt::TextureFormat::Rgba16Float) + } Some(crate::SurfaceCapabilities { formats, From ba2f00a8971111cde93e61c15cabbb7df3b210fe Mon Sep 17 00:00:00 2001 From: Andreas Reich Date: Sat, 8 Oct 2022 10:16:42 +0200 Subject: [PATCH 4/4] allow float16 framebuffer for webgl --- wgpu-hal/src/gles/adapter.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/wgpu-hal/src/gles/adapter.rs b/wgpu-hal/src/gles/adapter.rs index 3730fddaa5..8e2eda06f9 100644 --- a/wgpu-hal/src/gles/adapter.rs +++ b/wgpu-hal/src/gles/adapter.rs @@ -799,7 +799,6 @@ impl crate::Adapter for super::Adapter { wgt::TextureFormat::Bgra8UnormSrgb, ]) } - #[cfg(not(target_arch = "wasm32"))] if self .shared .private_caps