diff --git a/CHANGELOG.md b/CHANGELOG.md index 421e64184a..59a1921c52 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -161,6 +161,7 @@ By @cwfitzgerald in [#5325](https://github.com/gfx-rs/wgpu/pull/5325). #### GLES - Fixes for being able to use an OpenGL 4.1 core context provided by macOS with wgpu. By @bes in [#5331](https://github.com/gfx-rs/wgpu/pull/5331). +- Don't create a program for shader-clearing if that workaround isn't required. By @Dinnerbone in [#5348](https://github.com/gfx-rs/wgpu/pull/5348). #### Vulkan diff --git a/wgpu-hal/src/gles/adapter.rs b/wgpu-hal/src/gles/adapter.rs index 1576530451..306f25fb8f 100644 --- a/wgpu-hal/src/gles/adapter.rs +++ b/wgpu-hal/src/gles/adapter.rs @@ -4,6 +4,7 @@ use std::sync::{atomic::AtomicU8, Arc}; use wgt::AstcChannel; use crate::auxil::db; +use crate::gles::ShaderClearProgram; // https://webgl2fundamentals.org/webgl/lessons/webgl-data-textures.html @@ -875,7 +876,7 @@ impl super::Adapter { unsafe fn create_shader_clear_program( gl: &glow::Context, es: bool, - ) -> Option<(glow::Program, glow::UniformLocation)> { + ) -> Option { let program = unsafe { gl.create_program() }.expect("Could not create shader program"); let vertex = unsafe { Self::compile_shader( @@ -911,7 +912,10 @@ impl super::Adapter { unsafe { gl.delete_shader(vertex) }; unsafe { gl.delete_shader(fragment) }; - Some((program, color_uniform_location)) + Some(ShaderClearProgram { + program, + color_uniform_location, + }) } } @@ -937,9 +941,18 @@ impl crate::Adapter for super::Adapter { // Compile the shader program we use for doing manual clears to work around Mesa fastclear // bug. - let (shader_clear_program, shader_clear_program_color_uniform_location) = unsafe { - Self::create_shader_clear_program(gl, self.shared.es) - .ok_or(crate::DeviceError::ResourceCreationFailed)? + let shader_clear_program = if self + .shared + .workarounds + .contains(super::Workarounds::MESA_I915_SRGB_SHADER_CLEAR) + { + Some(unsafe { + Self::create_shader_clear_program(gl, self.shared.es) + .ok_or(crate::DeviceError::ResourceCreationFailed)? + }) + } else { + // If we don't need the workaround, don't waste time and resources compiling the clear program + None }; Ok(crate::OpenDevice { @@ -957,7 +970,6 @@ impl crate::Adapter for super::Adapter { copy_fbo: unsafe { gl.create_framebuffer() } .map_err(|_| crate::DeviceError::OutOfMemory)?, shader_clear_program, - shader_clear_program_color_uniform_location, zero_buffer, temp_query_results: Mutex::new(Vec::new()), draw_buffer_count: AtomicU8::new(1), diff --git a/wgpu-hal/src/gles/mod.rs b/wgpu-hal/src/gles/mod.rs index 70c487acf0..1762c09c1d 100644 --- a/wgpu-hal/src/gles/mod.rs +++ b/wgpu-hal/src/gles/mod.rs @@ -264,6 +264,11 @@ pub struct Device { render_doc: crate::auxil::renderdoc::RenderDoc, } +pub struct ShaderClearProgram { + pub program: glow::Program, + pub color_uniform_location: glow::UniformLocation, +} + pub struct Queue { shared: Arc, features: wgt::Features, @@ -271,9 +276,7 @@ pub struct Queue { copy_fbo: glow::Framebuffer, /// Shader program used to clear the screen for [`Workarounds::MESA_I915_SRGB_SHADER_CLEAR`] /// devices. - shader_clear_program: glow::Program, - /// The uniform location of the color uniform in the shader clear program - shader_clear_program_color_uniform_location: glow::UniformLocation, + shader_clear_program: Option, /// Keep a reasonably large buffer filled with zeroes, so that we can implement `ClearBuffer` of /// zeroes by copying from it. zero_buffer: glow::Buffer, diff --git a/wgpu-hal/src/gles/queue.rs b/wgpu-hal/src/gles/queue.rs index 6ec553bd29..5db5af9a16 100644 --- a/wgpu-hal/src/gles/queue.rs +++ b/wgpu-hal/src/gles/queue.rs @@ -40,10 +40,14 @@ fn get_z_offset(target: u32, base: &crate::TextureCopyBase) -> u32 { impl super::Queue { /// Performs a manual shader clear, used as a workaround for a clearing bug on mesa unsafe fn perform_shader_clear(&self, gl: &glow::Context, draw_buffer: u32, color: [f32; 4]) { - unsafe { gl.use_program(Some(self.shader_clear_program)) }; + let shader_clear = self + .shader_clear_program + .as_ref() + .expect("shader_clear_program should always be set if the workaround is enabled"); + unsafe { gl.use_program(Some(shader_clear.program)) }; unsafe { gl.uniform_4_f32( - Some(&self.shader_clear_program_color_uniform_location), + Some(&shader_clear.color_uniform_location), color[0], color[1], color[2],