mirror of
https://github.com/gfx-rs/wgpu.git
synced 2026-04-22 03:02:01 -04:00
webgl backend supports now non-srgb framebuffer (#3070)
This commit is contained in:
@@ -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
|
||||
|
||||
|
||||
@@ -786,27 +786,27 @@ impl crate::Adapter<super::Api> for super::Adapter {
|
||||
&self,
|
||||
surface: &super::Surface,
|
||||
) -> Option<crate::SurfaceCapabilities> {
|
||||
let mut formats = if surface.supports_srgb() {
|
||||
vec![
|
||||
wgt::TextureFormat::Rgba8UnormSrgb,
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
wgt::TextureFormat::Bgra8UnormSrgb,
|
||||
]
|
||||
} else {
|
||||
vec![
|
||||
if surface.presentable {
|
||||
let mut formats = 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 {
|
||||
];
|
||||
if surface.supports_srgb() {
|
||||
formats.extend(&[
|
||||
wgt::TextureFormat::Rgba8UnormSrgb,
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
wgt::TextureFormat::Bgra8UnormSrgb,
|
||||
])
|
||||
}
|
||||
if self
|
||||
.shared
|
||||
.private_caps
|
||||
.contains(super::PrivateCapabilities::COLOR_BUFFER_HALF_FLOAT)
|
||||
{
|
||||
formats.push(wgt::TextureFormat::Rgba16Float)
|
||||
}
|
||||
|
||||
Some(crate::SurfaceCapabilities {
|
||||
formats,
|
||||
present_modes: vec![wgt::PresentMode::Fifo], //TODO
|
||||
|
||||
@@ -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<Swapchain>,
|
||||
texture: Option<glow::Texture>,
|
||||
pub(super) presentable: bool,
|
||||
present_program: Option<glow::Program>,
|
||||
srgb_present_program: Option<glow::Program>,
|
||||
}
|
||||
|
||||
// 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<super::Api> 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() {
|
||||
|
||||
Reference in New Issue
Block a user