diff --git a/wgpu-hal/src/gles/adapter.rs b/wgpu-hal/src/gles/adapter.rs index 6ee5f713734..50e32996ec5 100644 --- a/wgpu-hal/src/gles/adapter.rs +++ b/wgpu-hal/src/gles/adapter.rs @@ -650,6 +650,10 @@ impl super::Adapter { // that's the only way to get gl_InstanceID to work correctly. features.set(wgt::Features::INDIRECT_FIRST_INSTANCE, supported); } + private_caps.set( + super::PrivateCapabilities::MULTISAMPLED_RENDER_TO_TEXTURE, + extensions.contains("GL_EXT_multisampled_render_to_texture"), + ); let max_texture_size = unsafe { gl.get_parameter_i32(glow::MAX_TEXTURE_SIZE) } as u32; let max_texture_3d_size = unsafe { gl.get_parameter_i32(glow::MAX_3D_TEXTURE_SIZE) } as u32; diff --git a/wgpu-hal/src/gles/command.rs b/wgpu-hal/src/gles/command.rs index 6136b4fd034..a11024c972e 100644 --- a/wgpu-hal/src/gles/command.rs +++ b/wgpu-hal/src/gles/command.rs @@ -558,10 +558,30 @@ impl crate::CommandEncoder for super::CommandEncoder { for (i, cat) in desc.color_attachments.iter().enumerate() { if let Some(cat) = cat.as_ref() { let attachment = glow::COLOR_ATTACHMENT0 + i as u32; + // Try to use the multisampled render-to-texture extension to avoid resolving + if let Some(ref rat) = cat.resolve_target { + if matches!(rat.view.inner, super::TextureInner::Texture { .. }) + && self.private_caps.contains( + super::PrivateCapabilities::MULTISAMPLED_RENDER_TO_TEXTURE, + ) + && !cat.ops.contains(crate::AttachmentOps::STORE) + // Extension specifies that only COLOR_ATTACHMENT0 is valid + && i == 0 + { + self.cmd_buffer.commands.push(C::BindAttachment { + attachment, + view: rat.view.clone(), + depth_slice: None, + sample_count: desc.sample_count, + }); + continue; + } + } self.cmd_buffer.commands.push(C::BindAttachment { attachment, view: cat.target.view.clone(), depth_slice: cat.depth_slice, + sample_count: 1, }); if let Some(ref rat) = cat.resolve_target { self.state @@ -584,6 +604,7 @@ impl crate::CommandEncoder for super::CommandEncoder { attachment, view: dsat.target.view.clone(), depth_slice: None, + sample_count: 1, }); if aspects.contains(crate::FormatAspects::DEPTH) && !dsat.depth_ops.contains(crate::AttachmentOps::STORE) diff --git a/wgpu-hal/src/gles/mod.rs b/wgpu-hal/src/gles/mod.rs index aad85106b10..0a489948002 100644 --- a/wgpu-hal/src/gles/mod.rs +++ b/wgpu-hal/src/gles/mod.rs @@ -232,6 +232,8 @@ bitflags::bitflags! { /// /// When this is true, instance offset emulation via vertex buffer rebinding and a shader uniform will be disabled. const FULLY_FEATURED_INSTANCING = 1 << 16; + /// Supports direct multisampled rendering to a texture without needing a resolve texture. + const MULTISAMPLED_RENDER_TO_TEXTURE = 1 << 17; } } @@ -924,6 +926,7 @@ enum Command { attachment: u32, view: TextureView, depth_slice: Option, + sample_count: u32, }, ResolveAttachment { attachment: u32, diff --git a/wgpu-hal/src/gles/queue.rs b/wgpu-hal/src/gles/queue.rs index 5ce0cac30b4..afb9f926bf7 100644 --- a/wgpu-hal/src/gles/queue.rs +++ b/wgpu-hal/src/gles/queue.rs @@ -111,6 +111,7 @@ impl super::Queue { attachment: u32, view: &super::TextureView, depth_slice: Option, + sample_count: u32, ) { match view.inner { super::TextureInner::Renderbuffer { raw } => { @@ -156,13 +157,24 @@ impl super::Queue { } else { unsafe { assert_eq!(view.mip_levels.len(), 1); - gl.framebuffer_texture_2d( - fbo_target, - attachment, - get_2d_target(target, view.array_layers.start), - Some(raw), - view.mip_levels.start as i32, - ) + if sample_count != 1 { + gl.framebuffer_texture_2d_multisample( + fbo_target, + attachment, + get_2d_target(target, view.array_layers.start), + Some(raw), + view.mip_levels.start as i32, + sample_count as i32, + ) + } else { + gl.framebuffer_texture_2d( + fbo_target, + attachment, + get_2d_target(target, view.array_layers.start), + Some(raw), + view.mip_levels.start as i32, + ) + } }; } } @@ -1119,9 +1131,17 @@ impl super::Queue { attachment, ref view, depth_slice, + sample_count, } => { unsafe { - self.set_attachment(gl, glow::DRAW_FRAMEBUFFER, attachment, view, depth_slice) + self.set_attachment( + gl, + glow::DRAW_FRAMEBUFFER, + attachment, + view, + depth_slice, + sample_count, + ) }; } C::ResolveAttachment { @@ -1139,6 +1159,7 @@ impl super::Queue { glow::COLOR_ATTACHMENT0, dst, None, + 1, ) }; unsafe {